| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 | <!DOCTYPE html><html><!--Copyright The Closure Library Authors. All Rights Reserved.Use of this source code is governed by the Apache License, Version 2.0.See the COPYING file for details.--><head><meta http-equiv="X-UA-Compatible" content="IE=edge">  <title>Closure Performance Tests - Vector Array math</title>  <link rel="stylesheet" type="text/css"        href="../testing/performancetable.css"/>  <script type="text/javascript" src="../base.js"></script>  <script type="text/javascript">    goog.require('goog.testing.jsunit');    goog.require('goog.testing.PerformanceTable');    goog.require('goog.vec.Vec4');    goog.require('goog.vec.Mat4');  </script></head><body>  <h1>Closure Performance Tests - Vector Array Math</h1>  <p>    <strong>User-agent:</strong>    <script type="text/javascript">document.write(navigator.userAgent);</script>  </p>  <p>    These tests compare various methods of performing vector operations on    arrays of vectors.  </p>  <div id="perfTable"></div>  <hr> <script type="text/javascript">var table = new goog.testing.PerformanceTable(    goog.dom.getElement('perfTable'));function createRandomFloat32Array(length) {  var array = new Float32Array(length);  for (var i = 0; i < length; i++) {    array[i] = Math.random();  }  return array;}function createRandomIndexArray(length) {  var array = [];  for (var i = 0; i < length; i++) {    array[i] = Math.floor(Math.random() * length);    array[i] = Math.min(length - 1, array[i]);  }  return array;}function createRandomVec4Array(length) {  var a = [];  for (var i = 0; i < length; i++) {    a[i] = goog.vec.Vec4.createFromValues(        Math.random(), Math.random(), Math.random(), Math.random());  }  return a;}function createRandomMat4() {  var m = goog.vec.Mat4.createFromValues(      Math.random(), Math.random(), Math.random(), Math.random(),      Math.random(), Math.random(), Math.random(), Math.random(),      Math.random(), Math.random(), Math.random(), Math.random(),      Math.random(), Math.random(), Math.random(), Math.random());  return m;}function createRandomMat4Array(length) {  var m = [];  for (var i = 0; i < length; i++) {    m[i] = createRandomMat4();  }  return m;}/** * Vec4Object is a 4-vector object with x,y,z,w components. * @param {number} x The x component. * @param {number} y The y component. * @param {number} z The z component. * @param {number} w The w component. * @constructor */Vec4Object = function(x, y, z, w) {  this.x = x;  this.y = y;  this.z = z;  this.w = w;};/** * Add two vectors. * @param {Vec4Object} v0 A vector. * @param {Vec4Object} v1 Another vector. * @param {Vec4Object} r The result. */Vec4Object.add = function(v0, v1, r) {  r.x = v0.x + v1.x;  r.y = v0.y + v1.y;  r.z = v0.z + v1.z;  r.w = v0.w + v1.w;};function createRandomVec4ObjectArray(length) {  var a = [];  for (var i = 0; i < length; i++) {    a[i] = new Vec4Object(        Math.random(), Math.random(), Math.random(), Math.random());  }  return a;}function setVec4FromArray(v, a, o) {  v[0] = a[o + 0];  v[1] = a[o + 1];  v[2] = a[o + 2];  v[3] = a[o + 3];}function setArrayFromVec4(a, o, v) {  a[o + 0] = v[0];  a[o + 1] = v[1];  a[o + 2] = v[2];  a[o + 3] = v[3];}/** * This is the same as goog.vec.Vec4.add().  Use this to avoid namespace lookup * overheads. * @param {goog.vec.Vec4.Vec4Like} v0 A vector. * @param {goog.vec.Vec4.Vec4Like} v1 Another vector. * @param {goog.vec.Vec4.Vec4Like} r The result. */function addVec4(v0, v1, r) {  r[0] = v0[0] + v1[0];  r[1] = v0[1] + v1[1];  r[2] = v0[2] + v1[2];  r[3] = v0[3] + v1[3];}function addVec4ByOffset(v0Buf, v0Off, v1Buf, v1Off, rBuf, rOff) {  rBuf[rOff + 0] = v0Buf[v0Off + 0] + v1Buf[v1Off + 0];  rBuf[rOff + 1] = v0Buf[v0Off + 1] + v1Buf[v1Off + 1];  rBuf[rOff + 2] = v0Buf[v0Off + 2] + v1Buf[v1Off + 2];  rBuf[rOff + 3] = v0Buf[v0Off + 3] + v1Buf[v1Off + 3];}function addVec4ByOptionalOffset(v0, v1, r, opt_v0Off, opt_v1Off, opt_rOff) {  if (opt_v0Off && opt_v1Off && opt_rOff) {    r[opt_rOff + 0] = v0[opt_v0Off + 0] + v1[opt_v1Off + 0];    r[opt_rOff + 1] = v0[opt_v0Off + 1] + v1[opt_v1Off + 1];    r[opt_rOff + 2] = v0[opt_v0Off + 2] + v1[opt_v1Off + 2];    r[opt_rOff + 3] = v0[opt_v0Off + 3] + v1[opt_v1Off + 3];  } else {    r[0] = v0[0] + v1[0];    r[1] = v0[1] + v1[1];    r[2] = v0[2] + v1[2];    r[3] = v0[3] + v1[3];  }}function mat4MultVec4ByOffset(mBuf, mOff, vBuf, vOff, rBuf, rOff) {  var x = vBuf[vOff + 0], y = vBuf[vOff + 1],      z = vBuf[vOff + 2], w = vBuf[vOff + 3];  rBuf[rOff + 0] = x * mBuf[mOff + 0] + y * mBuf[mOff + 4] +      z * mBuf[mOff + 8] + w * mBuf[mOff + 12];  rBuf[rOff + 1] = x * mBuf[mOff + 1] + y * mBuf[mOff + 5] +      z * mBuf[mOff + 9] + w * mBuf[mOff + 13];  rBuf[rOff + 2] = x * mBuf[mOff + 2] + y * mBuf[mOff + 6] +      z * mBuf[mOff + 10] + w * mBuf[mOff + 14];  rBuf[rOff + 3] = x * mBuf[mOff + 3] + y * mBuf[mOff + 7] +      z * mBuf[mOff + 11] + w * mBuf[mOff + 15];}var NUM_ITERATIONS = 200000;function testAddVec4ByOffset() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          addVec4ByOffset(a0, i * 4, a1, i * 4, a2, i * 4);        }      },      'Add vectors using offsets');}function testAddVec4ByOptionalOffset() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          addVec4ByOptionalOffset(a0, a1, a2, i * 4, i * 4, i * 4);        }      },      'Add vectors with optional offsets (requires branch)');}/** * Check the overhead of using an array of individual * Vec4s (Float32Arrays of length 4). */function testAddVec4ByVec4s() {  var nVecs = NUM_ITERATIONS;  var a0 = createRandomVec4Array(nVecs);  var a1 = createRandomVec4Array(nVecs);  var a2 = createRandomVec4Array(nVecs);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          addVec4(a0[i], a1[i], a2[i]);        }      },      'Add vectors using an array of Vec4s (Float32Arrays of length 4)');}function testAddVec4ByTmp() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  table.run(      function() {        var t0 = new Float32Array(4);        var t1 = new Float32Array(4);        for (var i = 0; i < nVecs; i++) {          setVec4FromArray(t0, a0, i * 4);          setVec4FromArray(t1, a1, i * 4);          addVec4(t0, t1, t0);          setArrayFromVec4(a2, i * 4, t0);        }      },      'Add vectors using tmps');}/** * Check the overhead of using an array of Objects with the implicit hash * lookups for the x,y,z,w components. */function testAddVec4ByObjects() {  var nVecs = NUM_ITERATIONS;  var a0 = createRandomVec4ObjectArray(nVecs);  var a1 = createRandomVec4ObjectArray(nVecs);  var a2 = createRandomVec4ObjectArray(nVecs);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          Vec4Object.add(a0[i], a1[i], a2[i]);        }      },      'Add vectors using an array of Objects ' +      '(with implicit hash lookups for the x,y,z,w components)');}function testAddVec4BySubarray() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          var t0 = a0.subarray(i * 4 * 4);          var t1 = a1.subarray(i * 4 * 4);          var t2 = a2.subarray(i * 4 * 4);          addVec4(t0, t1, t2);        }      },      'Add vectors using Float32Array.subarray()');}function testAddVec4ByView() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          var t0 = new Float32Array(a0.buffer, i * 4 * 4);          var t1 = new Float32Array(a1.buffer, i * 4 * 4);          var t2 = new Float32Array(a2.buffer, i * 4 * 4);          addVec4(t0, t1, t2);        }      },      'Add vectors using Float32 view');}function testMat4MultVec4ByOffset() {  var nVecs = NUM_ITERATIONS;  var nVecVals = nVecs * 4;  var nMatVals = nVecs * 16;  var m = createRandomFloat32Array(nMatVals);  var a0 = createRandomFloat32Array(nVecVals);  var a1 = new Float32Array(nVecVals);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          mat4MultVec4ByOffset(m, i * 16, a0, i * 4, a1, i * 4);        }      },      'vec4 = mat4 * vec4 using offsets.');}/** * Check the overhead of using an array of individual * Vec4s (Float32Arrays of length 4). */function testMat4MultVec4ByVec4s() {  var nVecs = NUM_ITERATIONS;  var a0 = createRandomVec4Array(nVecs);  var a1 = createRandomVec4Array(nVecs);  var m = createRandomMat4Array(nVecs);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          goog.vec.Mat4.multVec4(m[i], a0[i], a1[i]);        }      },      'vec4 = mat4 * vec4  using arrays of Vec4s and Mat4s');}/** * Do 10x as many for the one vector tests. * @type {number} */var NUM_ONE_ITERATIONS = NUM_ITERATIONS * 10;function testAddOneVec4ByOffset() {  var a0 = createRandomFloat32Array(4);  var a1 = createRandomFloat32Array(4);  var a2 = new Float32Array(4);  table.run(      function() {        for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {          addVec4ByOffset(a0, 0, a1, 0, a2, 0);        }      },      'Add one vector using offset of 0');}function testAddOneVec4() {  var a0 = createRandomFloat32Array(4);  var a1 = createRandomFloat32Array(4);  var a2 = new Float32Array(4);  table.run(      function() {        for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {          addVec4(a0, a1, a2);        }      },      'Add one vector');}function testAddOneVec4ByOptionalOffset() {  var a0 = createRandomFloat32Array(4);  var a1 = createRandomFloat32Array(4);  var a2 = new Float32Array(4);  table.run(      function() {        for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {          addVec4ByOptionalOffset(a0, a1, a2);        }      },      'Add one vector with optional offsets (requires branch)');}function testAddRandomVec4ByOffset() {  var nVecs = NUM_ITERATIONS;  var nVals = nVecs * 4;  var a0 = createRandomFloat32Array(nVals);  var a1 = createRandomFloat32Array(nVals);  var a2 = new Float32Array(nVals);  var i0 = createRandomIndexArray(nVecs);  var i1 = createRandomIndexArray(nVecs);  var i2 = createRandomIndexArray(nVecs);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          addVec4ByOffset(a0, i0[i] * 4, a1, i1[i] * 4, a2, i2[i] * 4);        }      },      'Add random vectors using offsets');}function testAddRandomVec4ByVec4s() {  var nVecs = NUM_ITERATIONS;  var a0 = createRandomVec4Array(nVecs);  var a1 = createRandomVec4Array(nVecs);  var a2 = createRandomVec4Array(nVecs);  var i0 = createRandomIndexArray(nVecs);  var i1 = createRandomIndexArray(nVecs);  var i2 = createRandomIndexArray(nVecs);  table.run(      function() {        for (var i = 0; i < nVecs; i++) {          addVec4(a0[i0[i]], a1[i1[i]], a2[i2[i]]);        }      },      'Add random vectors using an array of Vec4s');}// Make sure the tests are run in the order they are defined.var testCase = new goog.testing.TestCase(document.title);testCase.order = goog.testing.TestCase.Order.NATURAL;testCase.autoDiscoverTests();G_testRunner.initialize(testCase); </script></body></html>
 |