HTML Preparation code:
x
 
1
<!-- GITHUB: https://github.com/munrocket/double.js -->
2
<div style="display: none">
3
    <canvas id="withFloat" width="6" height="4"></canvas>
4
    <canvas id="withDoubleJs_Static" width="6" height="4"></canvas>
5
    <canvas id="withDoubleJs" width="6" height="4"></canvas>
6
    <canvas id="withDecimalJs" width="6" height="4"></canvas>
7
    <canvas id="withBigNumberJs" width="6" height="4"></canvas>
8
    <canvas id="withBigJs" width="6" height="4"></canvas>
9
    <canvas id="withBigFloat32" width="6" height="4"></canvas>
10
    <canvas id="withBigFloat53" width="6" height="4"></canvas>
11
  </div>
12
  <canvas id="splitTest" width="400" height="200" style="padding-left: 40px"></canvas>
13
  <canvas id="barChart" width="400" height="200" style="float:left"></canvas>
14
  <p style="display: none; font-family: 'Open Sans', sans;">
15
    All libraries except native float setted to precision with 31 decimal digits. <br/>
16
    To increase DoubleJs_Static performance we used static methods and .sqr() insted of .mul() in some places. <br/>
17
    To increase BigJs and BigNumberJs we used .round(31) and .dp(31) after each multiplication without this they become x1000 slower.<br/>
18
  </p>
19
20
<script src="https://cdn.jsdelivr.net/npm/double.js"></script>
21
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.0.1/decimal.min.js"></script>
22
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/7.2.1/bignumber.min.js"></script>
23
<script src="https://cdnjs.cloudflare.com/ajax/libs/big.js/5.1.2/big.min.js"></script>
24
<script src="https://cdn.jsdelivr.net/npm/bigfloat@0.1.1/dist/umd/index.js"></script>
Script Preparation code:
 
var maxIteration = 500, pixelId = 0;
var target = { x: -1.7490863748149414, y: -1e-25, dx: 3e-15, dy: 2e-15};
Tests:
  • double.js

     
    D = Double.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;
      }
    }
  • 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).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;
      }
    }
  • 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).lt(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;
      }
    }
  • 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).lt(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;
      }
    }
  • 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).cmp(4) < 0) {
          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;
      }
    }
Rendered benchmark preparation results:

Suite status: <idle, ready to run>

Previous results

Experimental features:

  • Test case name Result
    double.js
    decimal.js
    bignumber.js
    Big.js
    bigfloat.js BF32

    Fastest: N/A

    Slowest: N/A

Latest run results:
Run details: (Test run date: 3 months ago)
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36
Chrome Mobile 131 on Android
View result in a separate tab
Test name Executions per second
double.js 0.0 Ops/sec
decimal.js 10.5 Ops/sec
bignumber.js 18.4 Ops/sec
Big.js 11.1 Ops/sec
bigfloat.js BF32 10.7 Ops/sec