Repository navigation
Conversation
|
Thanks for this. I rebuilt the binary from the pinned The perf result doesn't reproduce on x86_64 Linux though (Node 22.21.1, isolated processes, trimmed mean of 7 batches, test/samples inputs). I also split the two flags to see which one is responsible:
angular / d3 / rollup unminified were -1% to -3%. So Suggestions:
Minor: with |
f45d1a0 to
07b764e
Compare
guybedford
left a comment
There was a problem hiding this comment.
Thanks for this, and for the careful measurements. I rebuilt the binary with the pinned toolchain (build-wasm-local, wasi-sdk 21 / binaryen 116) and it is byte-identical to the committed lib/lexer.wasm, and the full suite passes in all three modes.
I did an interleaved A/B of flag variants on the same src/lexer.js, Node 22.21 / V8 12.4, Linux x86_64. Medians over 60 shuffled rounds after warmup, all after wasm-opt -Oz:
| Build | Size | Large samples | Medium (~3 KB) | Small (~150 B) |
|---|---|---|---|---|
-Oz (control) |
22401 | 0% | 0% | 0% |
-Oz -flto -mllvm -inline-threshold=150 (this PR) |
25065 | -2% | -5.5% | -7.6% |
-Oz -mllvm -inline-threshold=150 (no LTO) |
25522 | -1 to -2% | ||
-Oz -flto only |
22057 | within noise | ||
-O2 |
27121 | -12 to -14% | -10% | -12% |
-O3 |
27894 | -13% | -10% | -14% |
Cold start (import + init + first parse in fresh processes) was within noise across all of them, about 0.1 ms spread.
Two things fall out of this:
-fltoon its own does nothing here, which is expected for a single translation unit. The whole effect comes from the inline threshold.-mllvm -inline-thresholdis an internal LLVM option without a stability guarantee across clang versions, while plain-O2is a stable public flag and gave roughly twice the speedup for another ~2 KB.
So the real decision seems to be how much inlined binary size the loader is willing to pay, and if some is acceptable, -O2 looks like the better point on that curve. Could you run -O2 through your arm64 harness alongside the current flags? If it holds up there too, I'd prefer that over the LTO / threshold pair.
Separately, the stack is based on 2.3.0 and the src/lexer.js change in #134 conflicts with #131 on main, so both will need a rebase before landing.
| # These are project-specific and are expected to be kept intact | ||
| WASM_TARGET := -target wasm32-unknown-wasi | ||
| WASM_EXTRA_CFLAGS := -I include-wasm/ -Wno-logical-op-parentheses -Wno-parentheses -Oz | ||
| WASM_EXTRA_CFLAGS += -flto -mllvm -inline-threshold=150 |
There was a problem hiding this comment.
On a single translation unit -flto had no measurable effect on its own in my runs (see the table in the review body); the gain is entirely from the inline threshold. If the threshold approach stays, this could be dropped along with the -Wl,--mllvm duplicate below, but see the review for the -O2 comparison.
Link-time optimization and selective inlining reduce median warm parsing CPU by 12.7%, 8.8%, and 12.5% for small, medium, and large application modules. The control uses default flags. The binary grows from 22,639 to 25,277 bytes. Measurements use Node 22.23.4/V8 12.4 on macOS arm64 and five fresh processes. Each process has 50,000 warmup calls per variant and seven interleaved batches with trimmed CPU means. Median cold import, initialization, and first-file parsing measures 1.851 ms with default flags and 1.963 ms with this build. Signed-off-by: Ruben Bridgewater <ruben.bridgewater@datadoghq.com>
555cd7f to
7cabdf3
Compare
Link-time optimization and selective inlining reduce median warm parsing CPU by 12.7%, 8.8%, and 12.5% for small, medium, and large application modules. The control uses default flags. The binary grows from 22,639 to 25,277 bytes.
Measurements use Node 22.23.4/V8 12.4 on macOS arm64 and five fresh processes. Each process has 50,000 warmup calls per variant and seven interleaved batches with trimmed CPU means. Median cold import, initialization, and first-file parsing measures 1.851 ms with default flags and 1.963 ms with this build.