miller/pkg
John Kerl e8d19f6892 Lazy per-record hashing: ~15-30% faster on common workloads
Records (NewMlrmapAsRecord) eagerly allocated and populated a
map[string]*MlrmapEntry on construction whenever hashRecords was true
(the default). For streaming verbs that never look records up by key
(e.g. `mlr cat`) that map is pure overhead: a heap allocation plus N
map-inserts per record, and N more pointer-heavy objects for the GC to
scan. Profiling 1M-record CSV shows runtime allocation/GC machinery
dominating every workload, and `--no-hash-records` was 25-30% faster --
but that flag makes wide-record lookups O(n), the regression that
motivated hashing in #1506.

Make record hashing lazy instead: allocate no index up front; build it
in findEntry on the first lookup, and only when the record is wide
enough (FieldCount >= mlrmapHashThreshold) that linear search would
hurt. Narrow records and never-looked-up records never pay for a map;
wide records that are actually queried still get hash-accelerated
lookups, matching the old eager-hash default. DSL maps (NewMlrmap) keep
eager hashing to limit the behavioral surface.

This is transparent: findEntry already fell back to linear scan when
keysToEntries was nil, and every mutator already guarded on
keysToEntries != nil.

Measured (big.csv, 1M x 7 cols, default flags, best of 3):
  cat    0.62 -> 0.47  (~24%)
  put    1.08 -> 0.82  (~24%)
  stats1 0.66 -> 0.57  (~14%)
  sort   2.9  -> 2.0   (~30%)

Wide-column case protected: 60-col file with field lookups, lazy (1.42s)
matches old eager default (1.40s) and beats pure linear (1.55s).

Verified: go test ./pkg/... and full regression suite pass; output is
byte-identical to forced --hash-records for sort, stats1, cut,
wide-column put, and duplicate-key dedupe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:27:56 -04:00
..
auxents Performance and style fixes (#1981) 2026-02-18 09:19:31 -05:00
bifs Fix mlr -s shebang doc and reject arrays/maps in contains/index (#1658) (#2058) 2026-05-17 11:40:39 -04:00
cli Add --omd-aligned flag for column-padded markdown output (#2057) 2026-05-16 11:41:01 -04:00
climain Default to "cat" verb when none is supplied (#2060) 2026-05-17 12:13:21 -04:00
colorizer Multiple style updates (#1974) 2026-02-16 15:49:21 -05:00
dkvpx Add DKVPX file format (#2002) 2026-03-02 22:35:08 -05:00
dsl Fix mlr -s shebang doc and reject arrays/maps in contains/index (#1658) (#2058) 2026-05-17 11:40:39 -04:00
entrypoint Improve error propagation (#1975) 2026-02-16 16:48:41 -05:00
go-csv Some fixes for staticcheck (#2006) 2026-03-03 09:27:03 -05:00
input Fix data dropped from ragged implicit-header TSV/CSV-lite input (#1749) (#2059) 2026-05-17 11:46:59 -04:00
lib Fix column alignment for wide and combining Unicode chars (#1520, #379) (#2061) 2026-05-17 12:12:54 -04:00
mlrval Lazy per-record hashing: ~15-30% faster on common workloads 2026-06-19 11:27:56 -04:00
output Fix PPRINT alignment with multi-character OFS (#1819) (#2063) 2026-05-17 12:45:49 -04:00
parsing Replace GOCC parser-generator with PGPG (#2015) 2026-03-15 22:28:57 -04:00
pbnjay-strptime Performance and style fixes (#1981) 2026-02-18 09:19:31 -05:00
platform Performance and style fixes (#1981) 2026-02-18 09:19:31 -05:00
runtime Experiment with mlr script (#2009) 2026-03-05 20:14:32 -05:00
scan Performance and style fixes (#1981) 2026-02-18 09:19:31 -05:00
stream Multiple style updates (#1974) 2026-02-16 15:49:21 -05:00
terminals Default to "cat" verb when none is supplied (#2060) 2026-05-17 12:13:21 -04:00
transformers Apply join prefixes/rename to unpaired records (#1821) (#2062) 2026-05-17 12:35:58 -04:00
types Update performance docs (#1991) 2026-02-22 17:04:35 -05:00
version Post-6.18.1 release: back to 6.18.1-dev 2026-04-19 12:03:05 -04:00
README.md Export library code in pkg/ (#1391) 2023-09-10 17:15:13 -04:00

Please see ../../README-dev.md for an overview; please see each subdirectory for details about it.