double.js benchmark

JavaScript performance comparison

Test case created by munrocket

Preparation code

<!-- GITHUB: https://github.com/munrocket/double.js -->
<div style="display: none">
    <canvas id="withFloat" width="6" height="4"></canvas>
    <canvas id="withDoubleJs_Static" width="6" height="4"></canvas>
    <canvas id="withDoubleJs" width="6" height="4"></canvas>
    <canvas id="withDecimalJs" width="6" height="4"></canvas>
    <canvas id="withBigNumberJs" width="6" height="4"></canvas>
    <canvas id="withBigJs" width="6" height="4"></canvas>
    <canvas id="withBigFloat32" width="6" height="4"></canvas>
    <canvas id="withBigFloat53" width="6" height="4"></canvas>
  </div>
  <canvas id="splitTest" width="400" height="200" style="padding-left: 40px"></canvas>
  <canvas id="barChart" width="400" height="200" style="float:left"></canvas>
  <p style="display: none; font-family: 'Open Sans', sans;">
    All libraries except native float setted to precision with 31 decimal digits. <br/>
    To increase DoubleJs_Static performance we used static methods and .sqr() insted of .mul() in some places. <br/>
    To increase BigJs and BigNumberJs we used .round(31) and .dp(31) after each multiplication without this they become x1000 slower.<br/>
  </p>

<script src="https://cdn.jsdelivr.net/npm/double.js@0.0.8/dist/double.iife.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.0.1/decimal.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/7.2.1/bignumber.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/big.js/5.1.2/big.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bigfloat@0.1.1/dist/umd/index.js"></script>
      
<script>
Benchmark.prototype.setup = function() {
  var maxIteration = 500, pixelId = 0;
  var target = { x: -1.7490863748149414, y: -1e-25, dx: 3e-15, dy: 2e-15};
  

};
</script>

Preparation code output

<!-- GITHUB: https://github.com/munrocket/double.js --> <div style="display: none"> <canvas id="withFloat" width="6" height="4"></canvas> <canvas id="withDoubleJs_Static" width="6" height="4"></canvas> <canvas id="withDoubleJs" width="6" height="4"></canvas> <canvas id="withDecimalJs" width="6" height="4"></canvas> <canvas id="withBigNumberJs" width="6" height="4"></canvas> <canvas id="withBigJs" width="6" height="4"></canvas> <canvas id="withBigFloat32" width="6" height="4"></canvas> <canvas id="withBigFloat53" width="6" height="4"></canvas> </div> <canvas id="splitTest" width="400" height="200" style="padding-left: 40px"></canvas> <canvas id="barChart" width="400" height="200" style="float:left"></canvas> <p style="display: none; font-family: 'Open Sans', sans;"> All libraries except native float setted to precision with 31 decimal digits. <br/> To increase DoubleJs_Static performance we used static methods and .sqr() insted of .mul() in some places. <br/> To increase BigJs and BigNumberJs we used .round(31) and .dp(31) after each multiplication without this they become x1000 slower.<br/> </p>

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
double.js static
D = Double;
var canvas = document.getElementById('withDoubleJs_Static');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = D.Zero, y = D.Zero;
    var xx = D.Zero, xy = D.Zero, yy = D.Zero;
    var tx = new D(target.x), ty = new D(target.y);
    var tdx = new D(target.dx), tdy = new D(target.dy);
    var cx = D.add22(D.sub22(tx, tdx), D.div21(D.mul21(tdx, 2 * i), buffer.width));
    var cy = D.sub22(D.add22(ty, tdy), D.div21(D.mul21(tdy, 2 * j), buffer.height));
    while (iteration++ < maxIteration && D.lt21(D.add22(D.clone(xx), yy), 4)) {
      x = D.add22(D.sub22(xx, yy), cx);
      y = D.add22(D.add22(xy, xy), cy);
      xx = D.sqr2(D.clone(x));
      yy = D.sqr2(D.clone(y));
      xy = D.mul22(x, y);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…
double.js
D = Double;
var canvas = document.getElementById('withDoubleJs');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = D.Zero, y = D.Zero;
    var xx = D.Zero, xy = D.Zero, yy = D.Zero;
    var tx = new D(target.x), ty = new D(target.y);
    var tdx = new D(target.dx), tdy = new D(target.dy);
    var cx = tx.sub(tdx).add(tdx.mul(2 * i).div(buffer.width));
    var cy = ty.add(tdy).sub(tdy.mul(2 * j).div(buffer.height));
    while (iteration++ < maxIteration && xx.add(yy).lt(4)) {
      x = xx.sub(yy).add(cx);
      y = xy.add(xy).add(cy);
      xx = x.mul(x);
      yy = y.mul(y);
      xy = x.mul(y);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…
decimal.js
Decimal.set({ precision: 31 });
var Dec = Decimal;
var canvas = document.getElementById('withDecimalJs');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = new Dec(0), y = new Dec(0);
    var xx = new Dec(0), xy = new Dec(0), yy = new Dec(0);
    var tx = new Dec(target.x), ty = new Dec(target.y);
    var tdx = new Dec(target.dx), tdy = new Dec(target.dy);
    var cx = tx.sub(tdx).add(tdx.mul(2 * i).div(buffer.width));
    var cy = ty.add(tdy).sub(tdy.mul(2 * j).div(buffer.height));
    while (iteration++ < maxIteration && xx.add(yy).toString() < 4) {
      x = xx.sub(yy).add(cx);
      y = xy.add(xy).add(cy);
      xx = x.mul(x);
      yy = y.mul(y);
      xy = x.mul(y);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…
bignumber.js
BigNumber.set({ DECIMAL_PLACES: 31 });
var BN = BigNumber;
var canvas = document.getElementById('withBigNumberJs');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = new BN(0), y = new BN(0);
    var xx = new BN(0), xy = new BN(0), yy = new BN(0);
    var tx = new BN(target.x), ty = new BN(target.y);
    var tdx = new BN(target.dx), tdy = new BN(target.dy);
    var cx = tx.minus(tdx).plus(tdx.times(2 * i).div(buffer.width)).dp(31);
    var cy = ty.plus(tdy).minus(tdy.times(2 * j).div(buffer.height)).dp(31);
    while (iteration++ < maxIteration && xx.plus(yy).toString() < 4) {
      x = xx.minus(yy).plus(cx);
      y = xy.plus(xy).plus(cy);
      xx = x.times(x).dp(31);
      yy = y.times(y).dp(31);
      xy = x.times(y).dp(31);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…
Big.js
Big.DP = 31;
var canvas = document.getElementById('withBigJs');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = new Big(0), y = new Big(0);
    var xx = new Big(0), xy = new Big(0), yy = new Big(0);
    var tx = new Big(target.x), ty = new Big(target.y);
    var tdx = new Big(target.dx), tdy = new Big(target.dy);
    var cx = tx.sub(tdx).add(tdx.mul(2 * i).div(buffer.width)).round(31);
    var cy = ty.add(tdy).sub(tdy.mul(2 * j).div(buffer.height)).round(31);
    while (iteration++ < maxIteration && xx.add(yy).toString() < 4) {
      x = xx.sub(yy).add(cx);
      y = xy.add(xy).add(cy);
      xx = x.mul(x).round(31);
      yy = y.mul(y).round(31);
      xy = x.mul(y).round(31);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…
bigfloat.js BF32
BF = bigfloat.BigFloat32;
var canvas = document.getElementById('withBigFloat32');
var buffer = canvas.getContext('2d').createImageData(canvas.width, canvas.height);
for (var j = 0; j < buffer.height; j++) {
  for (var i = 0; i < buffer.width; i++) {
    var iteration = 0;
    var x = new Big(0), y = new Big(0);
    var xx = new Big(0), xy = new Big(0), yy = new Big(0);
    var tx = new Big(target.x), ty = new Big(target.y);
    var tdx = new Big(target.dx), tdy = new Big(target.dy);
    var cx = tx.sub(tdx).add(tdx.mul(2 * i).div(buffer.width)).round(31);
    var cy = ty.add(tdy).sub(tdy.mul(2 * j).div(buffer.height)).round(31);
    while (iteration++ < maxIteration && xx.add(yy).toString() < 4) {
      x = xx.sub(yy).add(cx);
      y = xy.add(xy).add(cy);
      xx = x.mul(x).round(31);
      yy = y.mul(y).round(31);
      xy = x.mul(y).round(31);
    }
    var color = (iteration == maxIteration) ? 0 : 256 * (maxIteration - (iteration * 25) % maxIteration) / maxIteration;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = color;
    buffer.data[pixelId++] = 255;
  }
}
pending…

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

Compare results of other browsers

0 Comments

All libraries except native float setted to precision with 31 decimal digits.
To increase DoubleJs_Static performance we used static methods and .sqr() insted of .mul() in some places.
To increase BigJs and BigNumberJs we used .round(31) and .dp(31) after each multiplication without this they become x1000 slower.