Playground
This page measures hayahash64 on your machine. Everything runs in your browser. Nothing is uploaded.
WebAssembly is a main target of hayahash. Baseline wasm gives every hash the same narrow toolkit: no SIMD, no AES, no 64×64→128 multiply. Native builds of rapidhash and XXH3 lean on exactly those extras. hayahash assumes the narrow toolkit from the start. The speed test below shows what that means.
The speed test
One wasm module of about 14 KB holds five hashes: hayahash64, ChibiHash v2, rapidhash v3, XXH3-64, and XXH64. It compiles from unmodified upstream sources with one compiler and one set of flags. The timing loops run inside wasm. Before the first measurement, the page recomputes the known answers of every hash and compares them. The test takes about ten seconds.
The playground needs JavaScript. The rest of the site does not.
| hash | 16 KiB | 1 MiB | relative |
|---|
| hash | 8 B | 64 B | 256 B | relative |
|---|
Why the order flips
The overview says that rapidhash v3 is the better default on native CPUs. This page shows hayahash in front. Both statements are true. The platform decides the order.
On x86-64 and ARM64, one or two instructions compute a wide
multiply (64×64→128 bits). rapidhash builds its
mixing step on that product. Baseline wasm has no such
instruction. Its only 64-bit multiply is
i64.mul, and that returns the low 64 bits. The
compiler must build each wide multiply from several narrow
multiplies, with shifts and carry adds, behind a helper call
(__multi3 in this module). XXH3-64 peaks with
SIMD, and baseline wasm has no SIMD in this build either.
hayahash never asks for the wide product, for SIMD, or for
AES. Each multiply in its loop is one i64.mul.
The tables above show what that difference costs.
On a native CPU the trade runs the other way. There the wide multiply costs almost nothing, and rapidhash wins small keys on every CPU we measured. The benchmarks page keeps that comparison. Wasm can change too. The wide-arithmetic proposal adds the missing instruction, and engines work on it now. When browsers ship it as a default, the gap on this page can narrow.
Method
-
The module compiles with
zig ccat-O3forwasm32-wasi, with no SIMD flags. rapidhash and xxHash come from pinned upstream commits. The sources and the build are intests/wasm. - One measurement is one call into the module. The input buffer already sits in wasm linear memory, so no copy and no JS boundary crossing is inside a timing loop.
- The pure-JS row runs the BigInt fallback engine of the npm package. It shows what JavaScript pays without wasm.
- The SHA-256 row uses WebCrypto and makes one call at a time, so the call overhead is part of the number. SHA-256 is a cryptographic hash. That is another job. The row gives scale against a fast native hash the browser ships.
- Each cell calibrates its iteration count to about 50 ms per round, runs 3 rounds, and keeps the best round. Browser timers are coarse on purpose. The rounds are long, so the timer step stays below a few percent of a reading.
- The small-key columns chain the seed. This measures dependent latency, the shape of a hash-table probe. Do not compare the values with independent-hash numbers from other sites.
- The known answers of the hayahash rows are pinned to a native build of the reference header. The deploy fails when they drift. quality.md describes the wider verification.
- A background tab, a hot laptop, or a busy machine lowers the numbers. Run the test twice and keep the better run.
The shootout module embeds rapidhash (MIT, copyright 2025 Nicolas De Carli) and xxHash (BSD 2-Clause, copyright 2012-2023 Yann Collet). ChibiHash and hayahash are public domain. The module is built at deploy time from the commits pinned in the Makefile. No release artifact contains it.
Hash your text
The hash value comes from the same code the npm package ships: the reference header compiled to a 1.4 KB wasm module, with a pure-JS fallback. Type and watch.
hash value:
Hash a file
Pick a file. The file stays in your browser. The page reads it into memory and hashes it with seed 0 in one call through the npm package, input copy included. A big file shows the bulk rate best.