Yegor Gaidar
Available · Q4 2026
Lab / 02 · benchmark

One scoring pass,
three implementations.

Seven fraud rules over synthetic payment records: objects with real branches, the same maths over flat typed arrays, and a 218-byte WebAssembly module written byte by byte — no Rust, no wasm-pack, no toolchain of any kind. All three run on your CPU, and all three must return the identical flag count or this page refuses to show a ratio.

Correction — 2026-08-07. Until that date this URL was /lab/rust-wasm-fraud/ and claimed to compare JavaScript against a “Rust / WASM” engine, reporting speedups around 10×. It shipped no WebAssembly. The function labelled runWASM() was ordinary JavaScript over typed arrays, there was no .wasm file in the repository, and the number in the “WASM speedup” box measured JavaScript against other JavaScript under a label that said otherwise.

The old column has not been deleted — it is column B below, under its true name, because it turns out to be the most interesting column here: most of what people attribute to WebAssembly is data layout, and column B is the data layout without the WebAssembly.

old URL /lab/rust-wasm-fraud/ → 301 → this page · score.wasm, 218 bytes, served from this directory — check it in DevTools → Network → WASM
Controls median of N repetitions · never the minimum

reading environment…

Why there is no Rust here

Writing the bytes was cheaper than installing a compiler.

There is no Rust toolchain on the machine that builds this site — no rustc, no cargo, no wat2wasm, no clang --target=wasm32. Adding one to fix a page about honesty would have meant the page shipped weeks later, or shipped with the old claim still on it.

So tools/gen-wasm.mjs emits the binary format directly: LEB128 integers, five sections (type, function, memory, export, code), one function body. Nothing generates it at request time — it runs once, on my machine, and the 218 bytes are committed like any other asset. The generator refuses to write a file WebAssembly.validate() rejects, then checks the flag count against the JavaScript reference over 200,000 seeded records. If the two disagree it exits non-zero and the deploy does not publish.

The honest ratio

On this author's M-series laptop, in V8: B is about 2.7× faster than A, and C about 2.0× faster than B — roughly 5.5× end to end, with about three quarters of that coming from the data layout rather than from WebAssembly. Your numbers will differ and the page prints yours, not mine.

2.7×
B vs A · layout
2.0×
C vs B · wasm
≈75%
Of the gain is layout
218 B
The module itself

This workload is integer and f32 comparisons with no allocation and no calls — close to the best case for a JIT, which is why the wasm margin is 2× and not 10×. Workloads with dense f64 maths, manual memory or SIMD show more; a workload that crosses the JS↔wasm boundary per record shows less than 1×.

The write-up, corrected All labs