count leading zeros

JavaScript performance comparison

Revision 25 of this test case created by sjrd

Preparation code

<script>
var usingLogarithm = function (value) {
  value = value >>> 0;
  return value === 0 ? 32 : 32 - 1 - Math.floor(Math.log(value + 0.5) * Math.LOG2E);
};

var usingBitwiseOperations = function (x) {
  x = x >>> 0;
  // http://en.wikipedia.org/wiki/Find_first_set
  if (x === 0) {
    return 32;
  }
  var n = 0;
  if ((x & 0xFFFF0000) === 0) { n = n + 16; x = x << 16; }
  if ((x & 0xFF000000) === 0) { n = n + 8; x = x << 8; }
  if ((x & 0xF0000000) === 0) { n = n + 4; x = x << 4; }
  if ((x & 0xC0000000) === 0) { n = n + 2; x = x << 2; }
  if ((x & 0x80000000) === 0) { n = n + 1; }
  return n;
};

var usingBitwiseOperations2 = function (x) {
  x = x | 0;
  // http://en.wikipedia.org/wiki/Find_first_set
  // + trying to avoid uint32 to int32 conversions
  if (x === 0) {
    return 32;
  }
  var n = 0;
  if ((x & -65536)      === 0) { n = n | 16; x = x << 16; }
  if ((x & -16777216)   === 0) { n = n | 8; x = x << 8; }
  if ((x & -268435456)  === 0) { n = n | 4; x = x << 4; }
  if ((x & -1073741824) === 0) { n = n | 2; x = x << 2; }
  if ((x & -2147483648) === 0) { n = n | 1; }
  return n;
};

var usingToString = function (value) {
  // See https://bugs.ecmascript.org/show_bug.cgi?id=2465
  value = Number(value);
  var number = value >>> 0;
  if (number === 0) {
    return 32;
  }
  return 32 - (number).toString(2).length;
};

var usingLoop = function (value) {
  value = value | 0;
  var c = 32;
  while (value !== 0) {
    c -= 1;
    value >>>= 1;
  }
  return c;
};

if (Math.clz32 == undefined) {
  Math.clz32 = usingBitwiseOperations;
}

</script>

      
<script>
Benchmark.prototype.setup = function() {
  var i = Math.pow(2, 32) - 1;
  var clz = 0;
  var nextPower = Math.pow(2, 32);
  var MAX = Math.pow(2, 32);
  

};
</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
usingLogarithm
  if (usingLogarithm(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…
usingBitwiseOperations
  if (usingBitwiseOperations(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…
usingBitwiseOperations2
  if (usingBitwiseOperations2(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…
usingToString
  if (usingToString(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…
Math.clz32
  if (Math.clz32(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…
usingLoop
  if (usingLoop(i) !== clz) {
    throw new Error();
  }
  if (i === MAX - 1) {
    i = 0;
    clz = 32;
    nextPower = 1;
  } else {
    i += 1;
    if (i === nextPower) {
      clz -= 1;
      nextPower *= 2;
    }
  }
pending…

Compare results of other browsers

Revisions

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

0 Comments