Optimize FixedArray reverse iteration - #3784
Conversation
There was a problem hiding this comment.
Pull request overview
Optimizes FixedArray reverse-iteration helpers in the MoonBit core standard library by switching to unchecked element reads (unsafe_get) inside already bounds-controlled loops to reduce overhead.
Changes:
- Use
unsafe_getinsideFixedArray::rev_each,FixedArray::rev_eachi, andFixedArray::rev_foldloops. - Refactor
FixedArray::rev_foldito an explicit(read, index, acc)loop and useunsafe_getfor the reverse read.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
18df173 to
319a481
Compare
56cddde to
4835259
Compare
|
Three of this PR's four optimizations have already landed on main. The remaining piece — |
…iteration Completes PR #3784 (mizchi) on current main, where three of its four FixedArray reverse-iteration optimizations have already landed. The remaining delta is rev_foldi, which computed the ascending index as len - i - 1 on every iteration inside the descending range loop. Instead of that PR's C-style three-variable loop, the index becomes a second loop state of the same readable range form: for i in self.length()>..0; index = 0, acc = init { continue index + 1, f(index, acc, self.unsafe_get(i)) } Measured identical to the C-style loop (11.19 vs 11.20 us native) and faster than main on all three backends (rev_foldi, n=100K, sum fold): native 14.88 -> 11.19us (1.33x), js 72.4 -> 59.9us (1.21x), wasm-gc 75.5 -> 65.6us (1.15x). Per-element times (~0.1ns) show the fold is fully inlined and auto-vectorized in this benchmark; the win is the per-lane subtract dependency of len - i - 1 vectorizing worse than a counting index. With an opaque, non-inlinable closure the difference shrinks accordingly. Also adopts #3784's test pinning the reversed index/element pairing, which a miscounted index would break. Codex CLI review (xhigh, first-round sign-off): (index, element) pairing verified as (0,len-1)..(len-1,0) against the documented reverse-range and simultaneous-update semantics (f receives the pre-increment index); the pairing-test trace recomputed to 30120210; raise-polymorphism and the nobreak return intact; benchmark ratios recomputed (1.33x/1.21x/1.15x) and microbenchmark-scoped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Codex CLI <codex@openai.com>
Summary
Optimize reverse iteration helpers on
FixedArrayby using unchecked reads in the already bounds-controlled loops.This covers:
FixedArray::rev_eachFixedArray::rev_eachiFixedArray::rev_foldFixedArray::rev_foldiBenchmarks
Command:
moon bench -p moonbitlang/core/builtin -f array_locals_bench_test.mbt --target native --releaseFixedArray::rev_each n=100000FixedArray::rev_eachi n=100000FixedArray::rev_fold n=100000FixedArray::rev_foldi n=100000Validation
moon fmtmoon test builtin --target allmoon check builtin --target all --no-rendermoon infomoon bench -p moonbitlang/core/builtin -f array_locals_bench_test.mbt --target native --release