You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Plain number[] element access ~26x slower than Node in hot loops (community histogram benchmark); representation-selection Phase 4 territory #6904
Community-reported (Discord): an adaptive counting benchmark runs ~25× slower than Node. Reproduced and decomposed. The dominant cost is plain number[] element access (counts[v] read + write in a hot loop); function-call overhead is secondary; arithmetic itself is near-native.
Reproduction (deterministic variant, 5M iterations, byte-identical output vs Node)
Ablation (per-item ns, perry 0.5.1220 vs Node 26.3, same machine/load, ratios stable):
variant
Node
Perry
ratio
pure inline math (no call, no array)
1.6
4.6
~3×
+ random() as function call
10.5
35.4
3.4×
+ Int32Array counts
10.7
69.4
6.5×
+ plain number[] counts (packed, pre-filled)
9.4
244.7
26×
original shape (holey [])
9.2
263.1
29×
So of the ~214 ns/item on the original script: ~210 ns is the plain-array element read+write, ~31 ns the call, math is fine.
Analysis
The plain-array access lowers to guarded runtime machinery per access (typed-feedback numeric-index guard, write barrier, shadow-slot maintenance) because a number[] is a boxed-element heap array — every element read unboxes and every write reboxes + barriers, and V8-style packed-smi element storage does not exist.
Possible nearer-term slice, before full Phase 4: a packed-numeric-array representation for locally-created, never-escaping number[] whose writes are all proven numeric (this benchmark's counts qualifies: new Array(100).fill(0) or [], indexed only by a 0..99 int, values only count + 1). The existing packed-f64 loop-fact machinery covers counter-indexed shapes but not this value-indexed histogram shape.
Resolved by #6915 and #6916. The guarded numeric-array tiers and Ptr<NumArray> collector reduce the reported histogram path from ~26× Node to ~1.3× in the recorded measurement, with guard-free hot-loop IR and the deterministic benchmark retained at benchmarks/bench_histogram_numarray.ts.
Activity
perf(codegen+runtime): representation-selection Phase 4a — fast plain…
perf(codegen): representation-selection Phase 4a.3 — Ptr<NumArray> co…
proggeramlug commentedon Jul 30, 2026
Resolved by #6915 and #6916. The guarded numeric-array tiers and
Ptr<NumArray>collector reduce the reported histogram path from ~26× Node to ~1.3× in the recorded measurement, with guard-free hot-loop IR and the deterministic benchmark retained atbenchmarks/bench_histogram_numarray.ts.perf(codegen): integer-provenance locals are canonical raw f64 — type…
fix(runtime): module-global Uint8Array receivers, with the view-cache…