I've ported a bunch of hash functons to JS. These are all highly optimized for speed, and make use of ES6 features like Math.imul
and default parameters. Sadly, only algorithms made for 32-bit architectures get good performance in JS. Emulating 64-bit math can decrease performance by 80-90%.
Also see: CRC functions
Algorithm | Hash size | Speed | Notes |
---|---|---|---|
CRC-32 | 32-bit | 147/575 | For speed reference (it's pretty slow) |
FNV | 32-bit | 3041/2649 | variants: FNV-0, FNV-1, FNV-1a, FNV-1a_BM |
MurmurHash1 | 32-bit | 3296/2822 | Original version. Super fast. |
MurmurHash2 | 32-bit | 3027/2518 | aka MurmurHash2_x86_32 |
MurmurHash2A | 32-bit | 3053/2484 | Fixes a flaw in MurmurHash2. Uses Merkle–Damgård construction. |
MurmurHash3 | 32-bit | 3090/2515 | aka MurmurHash3_x86_32 |
xxHash | 32-bit | 2968/2492 | not as fast as you'd think, but still good |
SuperFastHash | 32-bit | -/- | Higher collision rates in some cases: 90 of 131072 (vs. Murmur3=0, Lookup2=2, Lookup3=3, xxHash=4) |
Marvin32 | 32-bit | -/- | Obscure function, but seems decent. Almost as fast as MurmurHash3. |
CityHash32 | 32-bit | -/- | The only 32-bit variant in Google's City/Farm families. Not recommended, it's just a slower Murmur3 clone. |
FunnyHash32 | 32-bit | -/- | Yet another 32-bit hash. |
Algorithm | Hash size | Speed | Notes |
---|---|---|---|
Lookup2_x86 | 32-bit | 2412/1985 | (Obsolete) 32-bit. 64/96-bit is possible but with worse statistics. |
Lookup3_x86 | 32/64-bit | 2553/1038 | 32 or 64-bit. 96 is possible but with weaker statistics. |
MurmurHash2_x86_64 | 64-bit | 2759/2406 | Slightly modified to avoid a flaw in the original, see comments. |
MurmurHash3_x86_128 | 128-bit | 2498/2162 | Modified version. Contains a possible flaw, see comments. |
MurmurHash2_160 | 160-bit | 1968/1590 | Unofficial mod that outputs five 32-bit hash states. |
HalfSipHash | 32/64-bit | -/- | 32-bit version of SipHash. Can output a 64-bit hash. Kind of slow. |
Legend (for Speed): 256 / 31488 (InputLength)
These numbers don't really mean much, just a quick comparison. They're all pretty fast. My fastest table CRC-32 is still ~75% slower than MurmurHash2_160
, which is the slowest in the table above.
MurmurHash3_x86_128
seems really fast considering it outputs 4 hashes, possibly one of the best choices for >32-bit.MurmurHash1
is fastest 32-bit hash in JS.MurmurHash3
andxxHash
are also very good for high quality hash.- If
xxHash
can be modified to properly mix v0-v4, this might be an efficient hash >32-bit. lookup2
produces 3 hahses, but its quality is only ensured for one of them.lookup3
is faster for 256, but is REALLY SLOW for 31488 (investigate). Unlikelookup2
, its quality is ensured for 64-bit.- I cannot recommend
MurmurHash2_x86_64
because of its flaw, and my modification that attempts to fix it needs to be benchmarked. MurmurHash2_160
is only one more 32-bit hash larger thanMurmurHash3_x86_128
but is quite slower. And cannot downscale without possibly hurting quality.CybBeta2
is my custom 64-bit hash. Decent speed, but not much faster thanMurmurHash2_x86_64
and has untested hash quality.CybBeta0
is my custom 32-bit hash. Only slightly faster thanMurmurHash1
and has untested hash quality.
I will put ports of 64-bit arithmetic hash functions here, but expect them to be extremely slow. If WebAssembly becomes viable that can be useful for 64-bit hash functions. BigInt does not currently seem to be a performant option.
- https://jsbench.me/fyjfja4xih/1 - MurmurHash3 benchmarks
- https://jsbench.me/2hjfj9oscd/1 - xxHash benchmarks
- https://jsbench.me/isjfj2rpkx/1 - comparison of available implementations
- https://jsbench.me/tgjfegz4er/1 - the guds
- https://jsbench.me/zrjfehfwgu/1 - the not-so-guds