Measured rather than guessed, and the guesses were wrong twice: the per-slot cell division and the block-size divisions were each replaced first, and neither moved the number. A profile named the four that did. The hash was FNV one byte at a time, a serial multiply chain per byte and a quarter of the operation. It is eight bytes at a time now, and a key that is one machine word — every integer, every enum, every bool, so very nearly every key — is one load and one mix with no loop at all. This is where "the hash is compiled concretely per key type" stops describing the arrangement and starts being the reason it is quick. Equality on eight bytes was a call into libc's vectorised memcmp, an eighth of the operation, and copying a value out was a call into memmove. Both are a load and a compare now for the sizes that are one word. The block geometry was recomputed five times over inside one function, and that function ran twice per lookup — once in the probe and once again in get. It is one struct built once and handed back. The seed was a five-multiply avalanche on the critical path of every probe, for mixing the hasher does again immediately afterwards; one multiply is all it has to do. And 64/size is a table, which is Odin's Map_Cell_Info by another route — Odin precomputes it per type because the probe loop must not divide, and the sizes reach this runtime as plain arguments. Numbers, on this machine, i64 to i64, against CPython 3.13's dict on the same workload. Cache-resident, 10k entries, 10M lookups: 21ns against 132ns, so about six times quicker. That is the answer to "is this another Python dict", and it is the one the design predicted. At a million entries it loses, 1.41s to 1.16s, and that is worth writing down rather than leaving out. Both are waiting on memory there, and this layout waits longer: keys, values and hashes are three separate runs, so a lookup that misses everything takes three cache misses where a compact dict takes two, and the hash run is a full eight bytes a slot. The layout buys probe locality, which is a win while the hash run is resident and a loss once nothing is.
Description
Languages
OCaml
67.2%
Emacs Lisp
15.2%
C
10.4%
HTML
2.9%
Standard ML
2.8%
Other
1.5%