MurmurHash3

Benchmark created on


Description

Performance of MurmurHash3 x86/32 ported to JS.

Setup

var MurmurHash3 = {
      mul32: function(m, n) {
        var nlo = n & 0xffff;
        var nhi = n - nlo;
        return ((nhi * m | 0) + (nlo * m | 0)) | 0;
      },
    
      hashBytes: function(data, len, seed) {
        var c1 = 0xcc9e2d51,
            c2 = 0x1b873593;
    
        var h1 = seed;
        var roundedEnd = len & ~0x3;
    
        for (var i = 0; i < roundedEnd; i += 4) {
          var k1 = (data.charCodeAt(i) & 0xff) | ((data.charCodeAt(i + 1) & 0xff) << 8) | ((data.charCodeAt(i + 2) & 0xff) << 16) | ((data.charCodeAt(i + 3) & 0xff) << 24);
    
          k1 = this.mul32(k1, c1);
          k1 = ((k1 & 0x1ffff) << 15) | (k1 >>> 17); // ROTL32(k1,15);
          k1 = this.mul32(k1, c2);
    
          h1 ^= k1;
          h1 = ((h1 & 0x7ffff) << 13) | (h1 >>> 19); // ROTL32(h1,13);
          h1 = (h1 * 5 + 0xe6546b64) | 0;
        }
    
        k1 = 0;
    
        switch (len % 4) {
        case 3:
          k1 = (data.charCodeAt(roundedEnd + 2) & 0xff) << 16;
          // fallthrough
        case 2:
          k1 |= (data.charCodeAt(roundedEnd + 1) & 0xff) << 8;
          // fallthrough
        case 1:
          k1 |= (data.charCodeAt(roundedEnd) & 0xff);
          k1 = this.mul32(k1, c1);
          k1 = ((k1 & 0x1ffff) << 15) | (k1 >>> 17); // ROTL32(k1,15);
          k1 = this.mul32(k1, c2);
          h1 ^= k1;
        }
    
        // finalization
        h1 ^= len;
    
        // fmix(h1);
        h1 ^= h1 >>> 16;
        h1 = this.mul32(h1, 0x85ebca6b);
        h1 ^= h1 >>> 13;
        h1 = this.mul32(h1, 0xc2b2ae35);
        h1 ^= h1 >>> 16;
    
        return h1;
      },
    
      hashString: function(data, len, seed) {
        var c1 = 0xcc9e2d51,
            c2 = 0x1b873593;
    
        var h1 = seed;
        var roundedEnd = len & ~0x1;
    
        for (var i = 0; i < roundedEnd; i += 2) {
          var k1 = data.charCodeAt(i) | (data.charCodeAt(i + 1) << 16);
    
          k1 = this.mul32(k1, c1);
          k1 = ((k1 & 0x1ffff) << 15) | (k1 >>> 17); // ROTL32(k1,15);
          k1 = this.mul32(k1, c2);
    
          h1 ^= k1;
          h1 = ((h1 & 0x7ffff) << 13) | (h1 >>> 19); // ROTL32(h1,13);
          h1 = (h1 * 5 + 0xe6546b64) | 0;
        }
    
        if ((len % 2) == 1) {
          k1 = data.charCodeAt(roundedEnd);
          k1 = this.mul32(k1, c1);
          k1 = ((k1 & 0x1ffff) << 15) | (k1 >>> 17); // ROTL32(k1,15);
          k1 = this.mul32(k1, c2);
          h1 ^= k1;
        }
    
        // finalization
        h1 ^= (len << 1);
    
        // fmix(h1);
        h1 ^= h1 >>> 16;
        h1 = this.mul32(h1, 0x85ebca6b);
        h1 ^= h1 >>> 13;
        h1 = this.mul32(h1, 0xc2b2ae35);
        h1 ^= h1 >>> 16;
    
        return h1;
      }
    };
    
    var i, s10, s1k, s1m = "",
        a10 = [], a1k = [];
    a10.length = 10;
    a1k.length = 1024;
    s10 = String.fromCharCode.apply(null, a10.map(function() {
      return ((Math.random() * 65536) | 0);
    }));
    s1k = String.fromCharCode.apply(null, a1k.map(function() {
      return ((Math.random() * 65536) | 0);
    }));
    for (i = 0; i < 1024; i++) s1m = s1m.concat(s1k);

Test runner

Ready to run.

Testing in
TestOps/sec
1k characters
MurmurHash3.hashString(s1k, s1k.length, 0)
ready
1k bytes
MurmurHash3.hashBytes(s1k, s1k.length, 0)
ready
1m characters
MurmurHash3.hashString(s1m, s1m.length, 0)
ready
1m bytes
MurmurHash3.hashBytes(s1m, s1m.length, 0)
ready
10 characters
MurmurHash3.hashString(s10, s10.length, 0)
ready
10 bytes
MurmurHash3.hashBytes(s10, s10.length, 0)
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.