TGViewer
igoroutine.courses igoroutine.courses @igoroutine_courses · 239 subscribers
Post #37 573
😎😎 Это изменение сломало Set на map[key]struct{}, который мы знали

В Go все привыкли писать set вот так:

type set[K comparable] struct {
data map[K]struct{}
}


Ибо многие знают, что в Go пустая структура не занимает память. Давайте посмотрим на формулировку из стандарта:
A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero.

поэтому, используя ее как значение в мапе, мы оптимизируем потребление памяти, ведь в реализации множества нам от мапы нужны только ключи.

😢😢 Но в Go 1.24 это сломали

Как было до Go 1.24?
Старая мапа была основана на бакетах, которые хранили отдельно список ключей и отдельно список значений. Грубо говоря, бакет можно было представить такой структурой:


type bmap struct {
tophash [8]uint8
keys [8]K
values [8]V
overflow *bmap
}


Массив пустых структур, как и сама пустая структура, не занимает память, значит, используя ее в качестве значения, мы выигрываем по памяти.

Что случилось в Go 1.24?
С переходом мапы на Swiss Tables структура бакетов поменялась. Теперь ключи и значения хранятся в специальных группах, но уже не в отдельных массивах, а в одной структуре:



type group struct {
ctrl uint64
slots [abi.SwissMapGroupSlots]struct {
key keyType
elem elemType
}
}


Что теперь произойдет, если использовать пустую структуру в качестве значения?

Дело в том, что, если struct{} стоит последним полем в структуре, происходят неприятные последствия.

Хотя сама пустая структура имеет нулевой размер, компилятор не может позволить указателю на последнее поле указывать за пределы объекта, поэтому он добавляет хвостовой байт (паддинг). А потом этот хвост еще может раздуться из-за выравнивания всей структуры (компилятор выравнивает структуры для большинства архитектур). То есть, теперь это поле с тем самым выравниваем будет занимать 8 байт, и наша оптимизация перестанет работать.

Как вы думаете, можно ли как-то решить эту проблему? Пишите свои варианты в комментариях.
  • 🤯 13
  • ❤ 7
  • 😱 4
More from @igoroutine_courses
  1. Jun 25, 2026Разбор задачи с порядком вызова функций в select Что будет выведено в stdout после запуска…
  2. Jun 24, 2026Post #40
  3. Jun 24, 2026photo post
  4. Mar 24, 2026😎😎 Это изменение сломало set на map[key]struct{}, который мы знали Продолжение предыдуще…
  5. Mar 5, 2026😎😎 От этого data race не спасает даже race detector Продолжение к предыдущему посту. Ита…
  6. Mar 4, 2026😢😢 От этого data race не спасает даже race detector Data race это частный случай race co…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →