The phm had a FIXED 8 buckets, so a 100-entry map was a ~12-entry linear scan per lookup — and phm-get walked the bucket twice (contains? then find). This went mostly unnoticed until the canonical zipmap (batch 2) started returning phms where kvs->map had built structs for scalar keys, regressing the map-read bench ~7x (jolt-s3y). phm-assoc now rehashes into a doubled bucket array when the count passes 2 entries/bucket (done on the fresh copy, so persistence is untouched); phm-get is single-pass with a presence flag (nil values still distinguish from missing); key= tries identity/scalar equality before paying for canonicalization; the bucket count is derived from (length (m :buckets)), not a constant, so any already-marshaled map keeps working. core-contains?'s phm branch goes through phm-contains? instead of poking buckets directly. map-read 48.5 -> 10.9 ms (the residual vs the pre-batch-2 6.7 is the canonicalizing-representation constant); map-build steady; bench TOTAL 4457 vs 4565 on main back-to-back. New unit case crosses the resize boundary at 500 entries: every key found, nil values present, collection keys canonical, dissoc + persistence intact. Gate: jpm exit 0, conformance 326x3. |
||
|---|---|---|
| .. | ||
| bench | ||
| clojure-stdlib/clojure | ||
| integration | ||
| spec | ||
| support | ||
| unit | ||