Home > Software engineering >  Does go use something like space padding for structs?
Does go use something like space padding for structs?

Time:08-03

I was playing around in go, and was trying to calculate and get the size of struct objects. And found something interesting, if you take a look at the following structs:

type Something struct {
        anInteger        int16 // 2 bytes
        anotherInt       int16 // 2 bytes
        yetAnother       int16 // 2 bytes
        someBool         bool  // 1 byte
} // I expected 7 bytes total

type SomethingBetter struct {
        anInteger        int16 // 2 bytes
        anotherInt       int16 // 2 bytes
        yetAnother       int16 // 2 bytes
        someBool         bool  // 1 byte
        anotherBool      bool  // 1 byte
} // I expected 8 bytes total

type Nested struct {
        Something // 7 bytes expected at first
        completingByte   bool // 1 byte
} // 8 bytes expected at first sight

But the result I got using unsafe.Sizeof(...) was as following:

Something         -> 8 bytes
SomethingBetter   -> 8 bytes
Nested            -> 12 bytes, still, after finding out that "Something" used 8 bytes, though this might use 9 bytes

I suspect that go does something kind of like padding, but I don't know how and why it does that, is there some formula? Or logics? If it uses space padding, is it done randomly? Or based on some rules?

CodePudding user response:

Yes, we have padding! if your system architecture is 32-bit the word size is 4 bytes and if it is 64-bit, the word size is 8 bytes. Now, what is the word size? "Word size" refers to the number of bits processed by a computer's CPU in one go (these days, typically 32 bits or 64 bits). Data bus size, instruction size, address size are usually multiples of the word size.
For example, suppose this struct:

type data struct {
        a bool     // 1 byte
        b int64    // 8 byte
}

This struct it's not 9 bytes because, when our word size is 8, for first cycle, cpu reads 1 byte of bool and padding 7 bytes for others.
Imagine:

p: padding
 ----------------------------------------- ---------------- 
| 1-byte bool | p | p | p | p | p | p | p |     int-64     |
 ----------------------------------------- ---------------- 
              first 8 bytes                 second 8 bytes

For better performance, sort your struct items from bigger to small.
This is not good performance:

type data struct {
    a string // 16 bytes            size 16
    b int32  //  4 bytes            size 20
    //           4 bytes padding    size 24
    c string // 16 bytes            size 40
    d int32  //  4 bytes            size 44
    //           4 bytes padding    size 48 - Aligned on 8 bytes
}

Now It's better:

type data struct {
    a string // 16 bytes            size 16
    c string // 16 bytes            size 32
    d int32  //  4 bytes            size 36
    b int32  //  4 bytes            size 40
    //           no padding         size 40 - Aligned on 5 bytes
}

See here for more examples.

  • Related