Компилятор Go выравнивает поля структур по границам их размера. Для этого он вставляет padding - неиспользуемые байты между полями. Порядок полей напрямую влияет на итоговый размер.
// Вариант 1: 24 байта
type S1 struct {
a bool // 1 байт + 7 padding (выравнивание int64 по 8)
b int64 // 8 байт
c bool // 1 байт + 7 padding (выравнивание структуры по 8)
}
// Вариант 2: 16 байт
type S2 struct {
b int64 // 8 байт
a bool // 1 байт
c bool // 1 байт + 6 padding
}
fmt.Println(unsafe.Sizeof(S1{})) // 24
fmt.Println(unsafe.Sizeof(S2{})) // 16
Каждое поле выравнивается по своему размеру: int64 по 8 байт, int32 по 4, bool и byte по 1. Структура в целом выравнивается по размеру самого большого поля.
Располагайте поля от большего к меньшему - это минимизирует padding:
// Оптимально:
type User struct {
ID int64 // 8
Score int32 // 4
Age int16 // 2
Active bool // 1 + 1 padding = 16 байт всего
}
Инструмент fieldalignment из golang.org/x/tools автоматически находит неоптимальные структуры.