Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ virtual function table memory cost

Consider:

class A
{
    public:
        virtual void update() = 0;
}

class B : public A
{
    public:
        void update() { /* stuff goes in here... */ }

    private:
        double a, b, c;
}

class C { 
  // Same kind of thing as B, but with different update function/data members
}

I'm now doing:

A * array = new A[1000];
array[0] = new B();
array[1] = new C();
//etc., etc.

If i call sizeof(B), the size returned is the size required by the 3 double members, plus some overhead required for the virtual function pointer table. Now, back to my code, it turns out that 'sizeof(myclass)' is 32; that is, I am using 24 bytes for my data members, and 8 bytes for the virtual function table (4 virtual functions). My question is: is there any way I can streamline this? My program will eventually use a heck of a lot of memory, and I don't like the sound of 25% of it being eaten by virtual functions pointers.

like image 623
Stewart Avatar asked Oct 26 '09 17:10

Stewart


People also ask

Are virtual functions expensive?

Virtual functions require an indirect call through the vtable, which is more expensive than a direct call due to interactions with branch prediction and the instruction cache, and also the prevention of further optimizations which could be carried out after inlining the call.

Are virtual function calls slow?

A virtual call requires at least an extra indexed dereference and sometimes a "fixup" addition, compared to a non-virtual call, which is simply a jump to a compiled-in pointer. Therefore, calling virtual functions is inherently slower than calling non-virtual functions.

Where is vtable memory stored?

Vtables themselves are generally stored in the static data segment, as they are class-specific (vs. object-specific).

What is the size of vtable?

vtables are static data per-type; d1 and d2 inherit a vtable-pointer from Parent which points to Derived 's vtable; All vtables point to an offset of 16 (0x10) bytes into the vtable.


3 Answers

The v-table is per class and not per object. Each object contains just a pointer to its v-table. So the overhead per instance is sizeof(pointer) (usually 4 or 8 bytes). It doesn't matter how many virtual functions you have for the sizeof the class object. Considering this, I think you shouldn't worry too much about it.

like image 71
Ponting Avatar answered Oct 01 '22 23:10

Ponting


Typically, every instance of a class with at least one virtual function will have an extra pointer stored with its explicit data members.

There's no way round this, but remember that (again typically) each virtual function table is shared between all instances of the class, so there is no great overhead to having multiple virtual functions or extra levels of inheritance once you've paid the "vptr tax" (small cost of vtable pointer).

For larger classes the overhead becomes much smaller as a percentage.

If you want functionality that does something like what virtual functions do, you are going to have to pay for it in some way. Actually using native virtual functions may well be the cheapest option.

like image 33
CB Bailey Avatar answered Oct 01 '22 22:10

CB Bailey


The space cost of a vtable is one pointer (modulo alignment). The table itself is not placed into each instance of the class.

like image 33
Nikolai Fetissov Avatar answered Oct 01 '22 23:10

Nikolai Fetissov