Skip to content

Instantly share code, notes, and snippets.

@vredens
Created October 21, 2021 09:06
Show Gist options
  • Save vredens/008a10b20fe3cf3a80539d676ec280fc to your computer and use it in GitHub Desktop.
Save vredens/008a10b20fe3cf3a80539d676ec280fc to your computer and use it in GitHub Desktop.
Go struct memory packing
// taken from https://play.golang.org/p/MBXg4UBOerp
package main
import (
"fmt"
"reflect"
)
type struct1 struct {
field1 bool
field2 bool
field3 bool
field4 int8
field5 bool
}
type struct2 struct {
field1 bool
field2 bool
field3 bool
field4 int16
field5 bool
}
type struct3 struct {
field1 bool
field2 bool
field3 int16
field4 int64
field5 bool
}
// Random order
type struct4 struct {
field1 bool
field2 int64
field3 bool
field4 int64
field5 bool
field6 bool
field7 bool
field8 int64
field9 bool
}
// Grouped by type
type struct5 struct {
field1 bool
field2 bool
field3 bool
field4 bool
field5 bool
field6 bool
field7 int64
field8 int64
field9 int64
}
func detail(structType reflect.Type) {
// Create a map of runes for each byte of the struct
memoryMap := make([]rune, structType.Size())
for i := range memoryMap {
memoryMap[i] = '_'
}
fields := reflect.VisibleFields(structType)
// Mark memory slots
for _, field := range fields {
for i := field.Offset; i < field.Offset+field.Type.Size(); i++ {
// Set as last character of the field name
memoryMap[i] = rune(field.Name[len(field.Name)-1])
}
}
fmt.Printf("%d bytes:\t%s\n", structType.Size(), string(memoryMap))
}
func main() {
fmt.Println("\nBiggest type size is 1 (bool, int8)")
detail(reflect.TypeOf((struct1{})))
fmt.Println("\nBiggest type size is 2 (int16)")
detail(reflect.TypeOf((struct2{})))
fmt.Println("\nBiggest type size is 8 (int64)")
detail(reflect.TypeOf((struct3{})))
fmt.Println("\nThese are same structs with different order:")
detail(reflect.TypeOf((struct4{})))
detail(reflect.TypeOf((struct5{})))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment