gostructpaddingmemory-alignment

Optimising datastructure/word alignment padding in golang


Similar to what I've learned in C++, I believe it's the padding that causes a difference in the size of instances of both structs.

type Foo struct {
    w byte //1 byte
    x byte //1 byte
    y uint64 //8 bytes
}
type Bar struct {
    x byte //1 byte
    y uint64 //8 bytes
    w byte// 1 byte
}
func main() {
    fmt.Println(runtime.GOARCH)
    newFoo := new(Foo)
    fmt.Println(unsafe.Sizeof(*newFoo))
    newBar := new(Bar)
    fmt.Println(unsafe.Sizeof(*newBar))
}

Output:

amd64
16
24

Solution

  • Currently there's no compile-time optimisation; the values are padded to 8 bytes on x64.

    You can manually arrange structs to optimally utilise space; typically by going from larger types to smaller; 8 consecutive byte fields for example, will only use 8 bytes, but a single byte would be padded to an 8 byte alignment, consider this: https://play.golang.org/p/0qsgpuAHHp

    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    type Compact struct {
        a, b                   uint64
        c, d, e, f, g, h, i, j byte
    }
    
    // Larger memory footprint than "Compact" - but less fields!
    type Inefficient struct {
        a uint64
        b byte
        c uint64
        d byte
    }
    
    func main() {
        newCompact := new(Compact)
        fmt.Println(unsafe.Sizeof(*newCompact))
        newInefficient := new(Inefficient)
        fmt.Println(unsafe.Sizeof(*newInefficient))
    }
    

    If you take this into consideration; you can optimise the memory footprint of your structs.