Go

What changed in Go 1.24 with Swiss Tables? Why are they faster?

Question 56HardGo 1.22 to 1.25

Go 1.24 replaced the bucket-chaining map with an implementation based on Swiss Tables (Google's Abseil design), in internal/runtime/maps. The design has several parts:

  • Groups: 8 slots plus one 8-byte control word. Each control byte marks its slot as empty, deleted (a tombstone), or full. A full slot also stores the 7-bit H2 part of the hash.
  • Hash split: H1 (the upper 57 bits) picks the starting group. H2 (the low 7 bits) is matched against all 8 control bytes at once using bit tricks (SWAR, or SIMD on amd64). Most failed lookups end after checking one control word, without touching any keys.
  • Open addressing with quadratic probing over groups. There are no overflow chains, which gives better cache locality.
  • The maximum load factor is 7/8, compared with 6.5/8 before, so maps use less memory.
  • Extendible hashing: a map is a directory of tables, and each table holds at most 1024 slots. When one table fills up, only that table splits. This bounds the worst-case latency of a single insert without the old incremental-evacuation machinery.
  • Small maps (8 entries or fewer) use a single group with no directory.

The Go team reported map operations up to 60% faster in some microbenchmarks (especially for large maps), and about a 1.5% geometric-mean CPU improvement across full-application benchmarks. The semantics are unchanged: iteration order is still random, there is still no &m[k], concurrent writes are still fatal, and maps still do not shrink. In Go 1.24 you could turn it off with GOEXPERIMENT=noswissmap.

Signal: you know implementation details are not part of the spec, and your code must not depend on them.

More on Arrays, Slices, Maps & Strings

All 37 Arrays, Slices, Maps & Strings questions