What happened
Three hot operations each lower to an opaque js_* runtime helper and land well
behind the Hermes interpreter. Perry 0.5.1220 vs Node v22 (V8) vs Hermes 1.0.0
(built from main), best of 5, macOS arm64; identical checksums across engines.
| Op |
Perry |
Node |
Hermes |
Perry/Hermes |
DataView set/getFloat64 (300×4096) |
205 ms |
1 ms |
34 ms |
6x |
Array.prototype.concat (20000×1024) |
686 ms |
11 ms |
23 ms |
30x |
regex .match() w/ 4 groups (300k) |
237 ms |
12 ms |
67 ms |
~3.5x |
Regex matching without extraction (RegExp.test()) is separately fast — the
cost is in materializing capture arrays / accessor results, i.e. the helper
call, not the regex engine.
What you expected
At least Hermes-interpreter throughput on these ops.
Minimal reproduction
// DataView — 6x
function dv() { var N=4096, b=new ArrayBuffer(N*8), v=new DataView(b), a=0;
for (var r=0;r<300;r++){ for(var i=0;i<N;i++) v.setFloat64(i*8,i*1.5+r,true);
for(var i=0;i<N;i++) a+=v.getFloat64(i*8,true);} return Math.round(a); }
// Array.concat — 30x (arrays built once, concat isolated)
function cc() { var N=512,x=[],y=[]; for(var i=0;i<N;i++){x.push(i);y.push(i+N);}
var a=0; for(var r=0;r<20000;r++){ a+=[].concat(x,y).length; } return a; }
// regex match with capture groups — ~3.5x
function rm() { var s="2026-07-13 key=42 val=99", re=/(\d{4})-(\d{2})-(\d{2}) key=(\d+)/, a=0;
for (var i=0;i<300000;i++){ var m=s.match(re); if(m) a+=m[1].length+m[4].length; } return a; }
perry compile x.js -o x && ./x # vs node x.js / hermes -O x.js
Environment
- Perry version: 0.5.1220
- Host OS: macOS 27.0 (arm64)
- Target: native
- Installed via: npm
Diagnostic output
DataView perry 205ms | node 1ms | hermes 34ms (chk=3957657600 all)
concat perry 686ms | node 11ms | hermes 23ms (chk=20480000 all)
regexMatch perry 237ms | node 12ms | hermes 67ms (chk=1800000 all)
Anything else
Likely instances of #6082 (helper declarations carry no LLVM attributes),
filed with per-op repros so each has a regression target — as typed-array
access got in #5525.
What happened
Three hot operations each lower to an opaque
js_*runtime helper and land wellbehind the Hermes interpreter. Perry 0.5.1220 vs Node v22 (V8) vs Hermes 1.0.0
(built from
main), best of 5, macOS arm64; identical checksums across engines.DataViewset/getFloat64 (300×4096)Array.prototype.concat(20000×1024).match()w/ 4 groups (300k)Regex matching without extraction (
RegExp.test()) is separately fast — thecost is in materializing capture arrays / accessor results, i.e. the helper
call, not the regex engine.
What you expected
At least Hermes-interpreter throughput on these ops.
Minimal reproduction
Environment
Diagnostic output
Anything else
Likely instances of #6082 (helper declarations carry no LLVM attributes),
filed with per-op repros so each has a regression target — as typed-array
access got in #5525.