I have a Voxel class which is being created half a million times. I have reduced the amount of data I am using, but it just occurred to me that I am not sure whether functions take up memory in a similar fashion as variables. How can I find out the amount of space a function takes in my program? More impo开发者_JAVA技巧rtantly, when I have 500 instances of a class, does that mean I have 500 instances of the function?
I can guess that that is most likely not the case (not taking into account inline functions), but an explanation would be nice.
Don't panic. Code for most functions (whether inline
or not) only occurs once in the linked binary.
Template methods occur once per instantiation, because different template parameters result in different code.
In this context, instantiation
means the use in your build of a class or function template with a specific set of template parameters. Each different set of parameters results in a new instantiation, though for class templates only the member functions that you actually use for each instantiation are included in your final binary image. More background here.
For Visual Studio make sure you enable link-time code generation, as this can further reduce code size by inspecting the full function set at link-time, as well as the usual compile-time optimizations that you should already have maxed out. You can also use /OPT:REF at link time to omit unreferenced functions. This is the default for Release builds, but worth double-checking.
No, there is only one instance of the function per template iteration. All the objects of a class refer to the same function instance.
Determining the code size of the function is non-trivial. Generating a link map is the most general means of determining function size, but it takes some education to read.
Unless you have virtual functions in that class - no, member functions do not take any space in the class instance. With virtual functions each instance has a single pointer to virtual function table.
What takes up space when creating a new object is the object data, not the machine code of the operations on that data – if you want to, you can think of member functions as »normal«, free functions which are implicitly passed a this
pointer.
For instance, from a codegen point of view, there is little difference between
struct A { int x; void foo(); };
and
struct A {};
void foo( A* self );
.
For virtual functions this is not entirely true because each virtual function adds a pointer to the vtable, but that's a different story.
精彩评论