Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
Compare hash functions with xxHash optimizations
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0
Browser:
Firefox 136
Operating system:
Windows
Device Platform:
Desktop
Date tested:
one year ago
Test name
Executions per second
webCryptoHash
40425.9 Ops/sec
fnv1a32
343099.2 Ops/sec
xxHash
1145236.1 Ops/sec
murmur3
625889.3 Ops/sec
xxHashOptimized
1234418.6 Ops/sec
xxHashUnrolled
1248070.5 Ops/sec
xxHashModern
1873964.4 Ops/sec
HTML Preparation code:
<!--your preparation HTML code goes here-->
Script Preparation code:
const testData = new Uint8Array(216); crypto.getRandomValues(testData); async function webCryptoHash(data) { const hash = await crypto.subtle.digest('SHA-1', data); return new Uint8Array(hash); } // 2. FNV-1a 32-bit (extremely fast, non-cryptographic) function fnv1a32(data) { let hash = 0x811c9dc5; for (let i = 0; i < data.length; i++) { hash ^= data[i]; hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24); } return hash >>> 0; } // 3. xxHash-like implementation (fast, non-cryptographic) function xxHash(data) { const PRIME32_1 = 0x9e3779b1; const PRIME32_2 = 0x85ebca77; const PRIME32_3 = 0xc2b2ae3d; let h = 0; for (let i = 0; i < data.length; i += 4) { const chunk = (data[i] || 0) | ((data[i + 1] || 0) << 8) | ((data[i + 2] || 0) << 16) | ((data[i + 3] || 0) << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); } return h >>> 0; } // 4. MurmurHash3-like implementation (fast, non-cryptographic) function murmur3(data) { const c1 = 0xcc9e2d51; const c2 = 0x1b873593; let h1 = 0; for (let i = 0; i < data.length; i += 4) { let k1 = (data[i] || 0) | ((data[i + 1] || 0) << 8) | ((data[i + 2] || 0) << 16) | ((data[i + 3] || 0) << 24); k1 = Math.imul(k1, c1); k1 = (k1 << 15) | (k1 >>> 17); k1 = Math.imul(k1, c2); h1 ^= k1; h1 = (h1 << 13) | (h1 >>> 19); h1 = Math.imul(h1, 5) + 0xe6546b64; } h1 ^= data.length; h1 ^= h1 >>> 16; h1 = Math.imul(h1, 0x85ebca6b); h1 ^= h1 >>> 13; h1 = Math.imul(h1, 0xc2b2ae35); h1 ^= h1 >>> 16; return h1 >>> 0; } function xxHashOptimized(data) { const PRIME32_1 = 0x9e3779b1; const PRIME32_2 = 0x85ebca77; let h = 0; let i = 0; // Process 4 items at once using a specialized loop for exactly 216 elements // 216 / 4 = 54 complete chunks while (i < 216) { const chunk = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); i += 4; } return h >>> 0; } function xxHashUnrolled(data) { const PRIME32_1 = 0x9e3779b1; const PRIME32_2 = 0x85ebca77; let h = 0; // Manually unroll the first few iterations // This removes loop overhead and helps branch prediction let chunk = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); chunk = data[4] | (data[5] << 8) | (data[6] << 16) | (data[7] << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); chunk = data[8] | (data[9] << 8) | (data[10] << 16) | (data[11] << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); // Process the rest in a tight loop for (let i = 12; i < 216; i += 4) { chunk = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24); h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); } return h >>> 0; } // Version optimized for modern JS engines function xxHashModern(data) { const PRIME32_1 = 0x9e3779b1; const PRIME32_2 = 0x85ebca77; let h = 0; const view = new DataView(data.buffer, data.byteOffset, data.byteLength); // Process 4 bytes at a time using DataView for (let i = 0; i < 216; i += 4) { const chunk = view.getUint32(i, true); // true for little-endian h = Math.imul(h + Math.imul(chunk, PRIME32_1), PRIME32_2); } return h >>> 0; } window.testData = testData; window.webCryptoHash = webCryptoHash; window.fnv1a32 = fnv1a32; window.xxHash = xxHash; window.murmur3 = murmur3; window.xxHashOptimized = xxHashOptimized; window.xxHashUnrolled = xxHashUnrolled; window.xxHashModern = xxHashModern;
Tests:
webCryptoHash
[Async/Deferred]
webCryptoHash(testData).then(() => { deferred.resolve(); });
fnv1a32
fnv1a32(testData);
xxHash
xxHash(testData);
murmur3
murmur3(testData);
xxHashOptimized
xxHashOptimized(testData);
xxHashUnrolled
xxHashUnrolled(testData);
xxHashModern
xxHashModern(testData);