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
[perf regression] JSON.parse high-volume throughput cliff on 0.5.1265 #7162
Between 0.5.1260 and 0.5.1265, JSON.parse of a small nested object in a hot
loop developed a throughput cliff: ~1 µs/parse up to ~10k parses, then a step
change to ~250–375 µs/parse.
Measurements (min ms, from-source builds, same host)
Control at N=20,000: manual build of the identical graph (no parse) = 12 ms on
1265; parsing any simpler shape ({"a":1}, one array, one string, 3-deep
nesting) = 2–7 ms. The trigger needs the full multi-container graph and high
volume — i.e. how JSON.parse allocates/tenures, not the allocation count.
Minimal reproduction
varSRC='{"id":42,"name":"fixture","active":true,"tags":["alpha","beta","gamma",7],"meta":{"level":3,"score":512,"child":{"k":9,"items":[1,2,3,4,5]}}}';functionwork(){varchk=0;for(vari=0;i<20000;i++){varo=JSON.parse(SRC);chk=(chk+o.id+o.meta.score)|0;}returnchk|0;}work();varbest=1e9,c;for(varr=0;r<3;r++){vart=Date.now();c=work();vard=Date.now()-t;if(d<best)best=d;}console.log(best+" ms");// ~43 ms on 0.5.1260, ~5800 ms on 0.5.1265
perry compile m.js -o m && ./m. Bisecting across the N=10k→20k knee should
localize it (window has several perf(gc)/nursery changes: #7076/#7079/#7088/#7051/#7057, open #7056).
Environment
Perry 0.5.1260 (2e105ca) vs 0.5.1265 (a3b31c0d), cargo build --release -p perry
from tagged source, each linked to its own full runtime. macOS 27.0 arm64.
Revalidated the issue's exact JSON.parse loop with Perry 0.5.1482 on Windows x86_64 (AMD Ryzen 5 7640HS), using five measured runs for each GC setting after a warm-up.
iterations
moving-loop polls on
moving-loop polls off
10,000
10-12 ms
10-11 ms
20,000
21-22 ms
20-22 ms
40,000
44-46 ms
41-50 ms
All runs produced the expected checksums. The reported 10k -> 20k jump from 12 ms to 5,842 ms is gone; throughput is approximately linear even with moving-loop polls explicitly enabled.
The regression window included #7019, which made the evacuating young-generation path and moving-loop polls default-on. #7161 disabled that path by default only about 3.5 hours after this issue was filed, and subsequent GC work has since made the enabled poll path linear for this reproducer as well.
Closing as already fixed; no code change or version bump is needed.
Activity
proggeramlug commentedon Aug 12, 2026
Revalidated the issue's exact
JSON.parseloop with Perry 0.5.1482 on Windows x86_64 (AMD Ryzen 5 7640HS), using five measured runs for each GC setting after a warm-up.All runs produced the expected checksums. The reported 10k -> 20k jump from 12 ms to 5,842 ms is gone; throughput is approximately linear even with moving-loop polls explicitly enabled.
The regression window included #7019, which made the evacuating young-generation path and moving-loop polls default-on. #7161 disabled that path by default only about 3.5 hours after this issue was filed, and subsequent GC work has since made the enabled poll path linear for this reproducer as well.
Closing as already fixed; no code change or version bump is needed.