733просмотров
27.0%от подписчиков
5 марта 2026 г.
Score: 806
🧩 Struct Padding: Как вы теряете гигабайты памяти на ровном месте Знаете это чувство, когда вы долго проектируете структуру, высчитываете типы, используете int8 вместо int, чтобы сэкономить память... а потом смотрите в профайлер и плачете? Вы думаете, что экономите память, а компилятор тихо посмеивается и подкидывает вам мусорные байты. Проблема в том, что железо читает память не побайтово, а "машинными словами" (обычно по 8 байт на 64-битных архитектурах). Чтобы CPU было удобно и быстро читать данные, компилятор Go выравнивает переменные в памяти, вставляя между ними пустые байты - Padding. Давайте смотреть на код. ❌ Плохо (Дуршлаг из паддинга): type BadStruct struct { a bool // 1 байт b int64 // 8 байт c bool // 1 байт
} Кажется, что размер структуры 1 + 8 + 1 = 10 байт?
По факту: вызов unsafe.Sizeof(BadStruct{}) вернет 24 байта!
Компилятор видит a (1 байт), понимает, что следующий b (8 байт) должен лежать на границе 8 байт, и вставляет 7 байт пустоты. Затем кладет c, и добивает конец структуры еще 7 байтами до ровного числа. ✅ Хорошо (Сортировка от большего к меньшему): type GoodStruct struct { b int64 // 8 байт a bool // 1 байт c bool // 1 байт
} Теперь unsafe.Sizeof(GoodStruct{}) равен 16 байтам. Мы сэкономили 33% памяти, просто поменяв строчки местами! А если у вас в in-memory кэше лежат миллионы таких объектов? Это гигабайты сэкономленной RAM на ровном месте. ☝️ Нюансы для Senior-ов: 🩵Не оптимизируйте всё подряд. Если структура создается один раз при старте приложения (например, Config) - забейте. Читаемость и логическая группировка полей важнее. Оптимизируйте только то, что массово аллоцируется, живет в больших слайсах или летает по сети. 🩵Автоматизация. Вам не нужно считать байты в уме. Включите линтер fieldalignment (он есть в составе go vet или golangci-lint). Он сам укажет на проблему сообщением вроде: "struct with 24 pointer bytes could be 16". #golang #performance #memory #optimization #underhood 👉 @golang_lib