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
When PropertyGet's receiver is statically typed Buffer / Uint8Array and the index is an int32 expression, lower inline:
cmp w_idx, w_len ; len loaded from buf once, hoisted out of loopb.hs .oob_trap_or_undefldrb w_out,[x_base, w_idx, uxtw]
…instead of bl js_buffer_get. For hot inner loops the length load is loop-invariant so it hoists once.
Expected impact
image_conv: 208M byte-reads per blur iter × ~40 instrs/read overhead ≈ 8.3B instructions of pure wrapper code per iteration. That matches the 6.9B cycles / 44B instructions we measured total. Removing the calls should drop the loop to ~1B instructions — projected 2686 ms → 400–600 ms, i.e. parity with Rust, possibly beating it.
Any tight Buffer loop: crypto, image processing, binary codec, hash functions — same shape.
Secondary: unblocks LLVM's autovectorizer — with the function calls gone it'll see a clean u8 → zext i32 → mul → add reduction and emit NEON umlal/uaddl widening-multiply-accumulate. Another 2–4× on top.
Pairing
Pairs with the integer-specialization work (filed separately) — the scvtf + NaN-box-wrapper calls should also vanish when the index/accumulator locals are provably int32-stable. Either issue lands individually worthwhile; together is multiplicative.
Repro
benchmarks/honest_bench/workloads/3_image_convolution/perry/image_conv.ts + the looped variant at /tmp/perry_repros/image_conv_loop.ts in the session that filed this. Profile method: sample <pid> 8 -file prof.txt on the release binary, then otool -tV on the binary for disassembly.
This was implemented in v0.5.38 (inline Buffer/Uint8Array bracket-access) and further optimized in v0.5.56 (i32-native index/value in Uint8ArrayGet/Set). The codegen now emits inline ldrb/strb with bounds checks instead of calling js_buffer_get/js_buffer_set. image_conv improved from 2.69s → 456ms across these versions.
Activity
perf: accumulator-pattern int-arithmetic fast path (closes #49, v0.5.…
proggeramlug commentedon Apr 16, 2026
This was implemented in v0.5.38 (inline Buffer/Uint8Array bracket-access) and further optimized in v0.5.56 (i32-native index/value in Uint8ArrayGet/Set). The codegen now emits inline
ldrb/strbwith bounds checks instead of callingjs_buffer_get/js_buffer_set. image_conv improved from 2.69s → 456ms across these versions.bench: honest_bench — 5-language perf comparison (Rust/Zig/Perry/Node…