2

I have a class and I want to reorganize it to avoid padding How can I do that? Shoud I worry about function order?

the class is:

class MyClass
{
    private:
    std::vector<std::pair<char,MyClass>> fils;
    std::string etiquette = "";
    unsigned int frequence = 0;

    void privateFunction1();
    void privateFunction2();
    void privateFunction3();

    public:
    MyClass();

    void publicFunction1();
    void publicFunction2();
    void publicFunction3();
};
Fractale
  • 1,503
  • 3
  • 19
  • 34
  • 3
    Why do you want to avoid padding? Padding is a feature, not an enemy. – Baum mit Augen Jul 17 '16 at 23:17
  • 7
    Unless you're targeting a memory-strapped embedded system (where memory is counted in a few kilobytes)I suggest you don't bother. Padding can make the structures better aligned in memory possibly leading to faster access times. – Some programmer dude Jul 17 '16 at 23:18
  • I need to reduce my memory consumption and a create a lot of object of this class – Fractale Jul 17 '16 at 23:19
  • When you say "a lot" what do you mean by that? A million? Ten? Hundreds of millions? For a few millions even a 32-bit system with a couple of gigs of memory is plenty. On a 64 bit systems with perhaps plenty of gigs or RAM don't bother unless you need several hundred millions. And even if you come over a few million there are perhaps other designs you should consider. – Some programmer dude Jul 17 '16 at 23:21
  • @JoachimPileborg I know, but just reordered attribute (and function) can in my case save me lot of space – Fractale Jul 17 '16 at 23:22
  • @JoachimPileborg Ten millions and my program should consume less than 500Mo and actually it consume 578Mo, I expect this optimization can reduce memory and consume less than 500Mo – Fractale Jul 17 '16 at 23:26
  • 2
    Well you can change the alignment and padding by *packing* the structure differently (and of course by rearranging the member variables). How to do that depends on the compiler you're using. That might save a couple of bytes for your class, but it won't be "recursive". The padding in the `std::vector` and `std::string` classes won't be changed. – Some programmer dude Jul 17 '16 at 23:30
  • 2
    Also, are the `fils` elements really supposed to be a pair of a character and an *instance* of the class? That makes a copy of the whole object. Maybe you should be using pointers instead? That might possibly save you a lot, depending on your use-case or course. Might be a better route to go than trying to pack the class. – Some programmer dude Jul 17 '16 at 23:33
  • 1
    I suspect the `etiquette` member of `std::string` type is an example of *stringly typed* code. Can it really have arbitrary strings as values? Or is there a limited set of possible values that can be encoded by an enumeration? – Cheers and hth. - Alf Jul 17 '16 at 23:36
  • changing the position of function or reordered it will change something or it's just the member variables? Sorry i don't understand when you say "it won't be recursive" – Fractale Jul 17 '16 at 23:37
  • fils (in english is son) was a map with key a char and with a value of type MyClass (consider MyClass like a node in a tree) I change it to a vector for reduce memory consuption. why use pointer will save me space? – Fractale Jul 17 '16 at 23:42
  • etiquette is not enumerable, it can take many value, and string can be very long – Fractale Jul 17 '16 at 23:47
  • 2
    Member functions take no space in an object (unless they are `virtual`) so reordering them doesn't matter, only the variables. Use a test program that prints the size of different variants using `sizeof`. For the packing, if you tell the compiler to pack the `MyClass` structure, then only that structure will be packed. The member variables that are in turn structures will not be packed. So you might save a couple of bytes of padding between `fils`, `etiquette` and `frequence` but that's it. The `std::vector` and `std::string` structures will not be packed. – Some programmer dude Jul 17 '16 at 23:47
  • ok thank you @JoachimPileborg :D – Fractale Jul 17 '16 at 23:53
  • Checkout the 'pack' compiler #pragma to turn off padding of structures – James Jul 18 '16 at 00:59

1 Answers1

4

As already mentioned in the comment, the functions and orders of functions is not important for the size.

There really should not be any padding in the MyClass structure itself (or at least not on a 32bit system, but you are not mentioning the cpu architecture), however the content of the std::vector and std::string is allocated outside the actual structure of the class.

As you can see in this answer the content of the vector is in contiguous memory allocated as you are adding data into the vector, and unless you are setting the capacity there may be a lot of overhead -- so the capacity() of the std::vector data within MyClass may add additional overhead.

The only structure where elimination of padding could save you anything would be in the std::pair<char, MyClass> .. you are not saying anything about how many element you are having in the std::vector, but if almost one for every possible char (i.e. almost 256), and since you are concerned about total memory consumption, then you may be better off using a

 MyClass *fils[256];

instead of

 std:vector< std:pair<char, MyClass> > fils

as you no longer will need to manage the capacity of the vector to get the exact space, and you have about the same amount of overhead as the std::pair when padded.

Also, the overhead of an empty std::string on my system is 32 bytes, so depending on what you are keeping in etiquette you may want to reconsider that as well -- for example if the etiquette in different instances of MyClass is duplicated, you may want to find a way of keeping a unique set of values and just a pointer from MyClass to the unique etiquette

YMMV.

Community
  • 1
  • 1
Soren
  • 14,402
  • 4
  • 41
  • 67