В этой статье я хочу объяснить вам, как внутренняя память работает в 64-битной архитектуре, когда вы создаете экземпляр структуры. (Вы можете поиграть с кодом https://play.golang.org/p/cUgB54yCpL)
Как память работает внутри:
Когда у вас есть такая структура:
type myStruct struct { myBool bool // 1 byte myFloat float64 // 8 bytes myInt int32 // 4 bytes }
Как видите, логическое значение занимает 1 байт, float64 - 8 байтов, а int32 - 4 байта.
Но в памяти выделяется последовательный пакет размером 8 байт. Итак, вместо того, чтобы брать 1 + 8 + 4 = 13 байт. Эта структура займет: 24 байта
a := myStruct{} fmt.Println(unsafe.Sizeof(a)) // 24 bytes
Потому что в памяти у нас будет:
Итак, 8 + 8 + 8 = 24 байта
Как оптимизировать:
Можно оптимизировать, упорядочив структуру по взятым байтам:
type myStructOptimized struct { myFloat float64 // 8 bytes myBool bool // 1 byte myInt int32 // 4 bytes }
Эта новая упорядоченная структура теперь займет:
b := myStructOptimized{} fmt.Println(unsafe.Sizeof(b)) // ordered 16 bytes
16 байт, потому что в памяти он будет размещен вот так (https://play.golang.org/p/gmkrt6X7aM):
8 + 8 = 16 байт
Как видите, для соблюдения выравнивания данных есть отступы (https://en.wikipedia.org/wiki/Data_structure_alignment). Это означает, что в некоторых случаях данные не оптимально выровнены по словам (в зависимости от во многих случаях процессор, кеш-память, виртуальная память), и иногда это может замедлить работу приложения, поэтому протестируйте все: D
Ссылки:
- Https://play.golang.org/p/cUgB54yCpL
- Https://github.com/Tkanos/optimizing-memory-by-ordering-struct-by-type
- Http://www.catb.org/esr/structure-packing/
- Https://en.wikipedia.org/wiki/Data_structure_alignment