DOMMatrix preMultiplySelf

JavaScript performance comparison

Test case created by stasm

Preparation code

<canvas></canvas>
      
<script>
Benchmark.prototype.setup = function() {
  let gl = document.querySelector("canvas").getContext("webgl2");
  
  function create() {
      let out = new Float32Array(16);
      out[0] = 1;
      out[5] = 1;
      out[10] = 1;
      out[15] = 1;
      return out;
  }
  
  function multiply(out, a, b) {
      let a00 = a[0],
          a01 = a[1],
          a02 = a[2],
          a03 = a[3];
      let a10 = a[4],
          a11 = a[5],
          a12 = a[6],
          a13 = a[7];
      let a20 = a[8],
          a21 = a[9],
          a22 = a[10],
          a23 = a[11];
      let a30 = a[12],
          a31 = a[13],
          a32 = a[14],
          a33 = a[15]; // Cache only the current line of the second matrix
  
      let b0 = b[0],
          b1 = b[1],
          b2 = b[2],
          b3 = b[3];
      out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = b[4];
      b1 = b[5];
      b2 = b[6];
      b3 = b[7];
  
      out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = b[8];
      b1 = b[9];
      b2 = b[10];
      b3 = b[11];
      out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      b0 = b[12];
      b1 = b[13];
      b2 = b[14];
      b3 = b[15];
      out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
      out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
      out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
      out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
      return out;
  }
  
  function composeArray(out, q, v, s) {
      // Quaternion math
      let x = q[0],
          y = q[1],
          z = q[2],
          w = q[3];
      let x2 = x + x;
      let y2 = y + y;
      let z2 = z + z;
      let xx = x * x2;
      let xy = x * y2;
      let xz = x * z2;
      let yy = y * y2;
      let yz = y * z2;
      let zz = z * z2;
      let wx = w * x2;
      let wy = w * y2;
      let wz = w * z2;
      let sx = s[0];
      let sy = s[1];
      let sz = s[2];
      out[0] = (1 - (yy + zz)) * sx;
      out[1] = (xy + wz) * sx;
      out[2] = (xz - wy) * sx;
      out[3] = 0;
      out[4] = (xy - wz) * sy;
      out[5] = (1 - (xx + zz)) * sy;
      out[6] = (yz + wx) * sy;
      out[7] = 0;
      out[8] = (xz + wy) * sz;
      out[9] = (yz - wx) * sz;
      out[10] = (1 - (xx + yy)) * sz;
      out[11] = 0;
      out[12] = v[0];
      out[13] = v[1];
      out[14] = v[2];
      out[15] = 1;
      return out;
  }
  
  function composeDOMMatrix(mat, q, v, s) {
      // Quaternion math
      let x = q[0],
          y = q[1],
          z = q[2],
          w = q[3];
      let x2 = x + x;
      let y2 = y + y;
      let z2 = z + z;
      let xx = x * x2;
      let xy = x * y2;
      let xz = x * z2;
      let yy = y * y2;
      let yz = y * z2;
      let zz = z * z2;
      let wx = w * x2;
      let wy = w * y2;
      let wz = w * z2;
      let sx = s[0];
      let sy = s[1];
      let sz = s[2];
      mat.m11 = (1 - (yy + zz)) * sx;
      mat.m12 = (xy + wz) * sx;
      mat.m13 = (xz - wy) * sx;
      mat.m14 = 0;
      mat.m21 = (xy - wz) * sy;
      mat.m22 = (1 - (xx + zz)) * sy;
      mat.m23 = (yz + wx) * sy;
      mat.m24 = 0;
      mat.m31 = (xz + wy) * sz;
      mat.m32 = (yz - wx) * sz;
      mat.m33 = (1 - (xx + yy)) * sz;
      mat.m34 = 0;
      mat.m41 = v[0];
      mat.m42 = v[1];
      mat.m43 = v[2];
      mat.m44 = 1;
  }
  
  let rotation1 = [1, 0, 0, 0];
  let translation1 = [4, 5, 6];
  let scale1 = [1, 2, 3];
  
  let rotation2 = [0, 1, 0, 0];
  let translation2 = [7, 8, 9];
  let scale2 = [3, 1, 2];
  
  let m1 = create();
  let m2 = create();
  
  let arr1 = [...m1];
  let arr2 = [...m2];
  
  let dom1 = new DOMMatrix(m1);
  let dom2 = new DOMMatrix(m2);

};
</script>

Preparation code output

<canvas></canvas>

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
DOMMatrix
composeDOMMatrix(dom1, rotation1, translation1, scale1);
composeDOMMatrix(dom2, rotation2, translation2, scale2);
dom2.preMultiplySelf(dom1);
pending…
Float32Array
composeArray(m1, rotation1, translation1, scale1);
composeArray(m2, rotation2, translation2, scale2);
multiply(m2, m1, m2);
pending…
Array
composeArray(arr1, rotation1, translation1, scale1);
composeArray(arr2, rotation2, translation2, scale2);
multiply(arr2, arr1, arr2);
pending…
DOMMatrix (gl)
composeDOMMatrix(dom1, rotation1, translation1, scale1);
composeDOMMatrix(dom2, rotation2, translation2, scale2);
dom2.preMultiplySelf(dom1);

gl.uniformMatrix4fv(null, false, dom2.toFloat32Array());
pending…
Array (gl)
composeArray(arr1, rotation1, translation1, scale1);
composeArray(arr2, rotation2, translation2, scale2);
multiply(arr2, arr1, arr2);

gl.uniformMatrix4fv(null, false, arr2);
pending…
Float32Array (gl)
composeArray(m1, rotation1, translation1, scale1);
composeArray(m2, rotation2, translation2, scale2);
multiply(m2, m1, m2);

gl.uniformMatrix4fv(null, false, m2);
pending…

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

0 Comments