Marshalling-test-v2.0.1

JavaScript performance comparison

Test case created by KriNeko

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  class itemType_HEADER {
  	static get _size() { return 8 }
  	get _size() { return 8 }
  
  }
  class matrix4x4_HEADER {
  	static get _size() { return 128 }
  	get _size() { return 128 }
  
  }
  class main_HEADER {
  	static get _size() { return 12800128 }
  	get _size() { return 12800128 }
  
  }
  class Marshalling {
  	
  	static get matrix4x4() { return matrix4x4_HEADER }
  	static get main() { return main_HEADER }
  	constructor(ARRAYBUFFER) {
  		
  		const DATAVIEW     = new DataView(ARRAYBUFFER);
  		const UINT8ARRAY   = new Uint8Array(ARRAYBUFFER);
  		const UINT16ARRAY  = new Uint16Array(ARRAYBUFFER);
  		const UINT32ARRAY  = new Uint32Array(ARRAYBUFFER);
  		const INT8ARRAY    = new Int8Array(ARRAYBUFFER);
  		const INT16ARRAY   = new Int16Array(ARRAYBUFFER);
  		const INT32ARRAY   = new Int32Array(ARRAYBUFFER);
  		const FLOAT32ARRAY = new Float32Array(ARRAYBUFFER);
  		const FLOAT64ARRAY = new Float64Array(ARRAYBUFFER);
  		
  		class _f0jigemxj0c {
  			constructor(array) {
  				this.array = array;
  				this.index = 0;
  			}
  
  			next() {
  				if ( this.index >= this.array.length )
  					return {done: true};
  			
  				const value = this.array.get(this.index);
  				this.index++;
  				return {done: false, value};
  			}
  		}
  		class _19d4rly6u4n { 
  			static get _size() { return 128 }
  			static get _align() { return undefined }
  
  			constructor(_offset_) {
  				this._offset = _offset_
  			}
  			
  			get _offset() { return this._offset_ }
  			set _offset(value) { this._offset_ = value | 0 }
  
  			get _size() { return 128 }
  			get _align() { return undefined }
  			
  			_fill(char) {
  				char |= 0;
  				for(let i = 0; i < 128; i++)
  					UINT8ARRAY[this._offset + i] = char;
  				return this
  			}
  			
  			_inc(count = 1) { this._offset += count * 128; return this }
  			_dec(count = 1) { this._offset -= count * 128; return this }
  			_next(count = 1) { return new this.constructor(this._offset + count * 128) }
  			_prev(count = 1) { return new this.constructor(this._offset - count * 128) }
  			
  			get _UINT8ARRAY() { return UINT8ARRAY }
  			get _UINT16ARRAY() { return UINT16ARRAY }
  			get _UINT32ARRAY() { return UINT32ARRAY }
  			get _INT8ARRAY() { return INT8ARRAY }
  			get _INT16ARRAY() { return INT16ARRAY }
  			get _INT32ARRAY() { return INT32ARRAY }
  			get _FLOAT32ARRAY() { return FLOAT32ARRAY }
  			get _FLOAT64ARRAY() { return FLOAT64ARRAY }
  		
  			get m00() { return FLOAT64ARRAY[(this._offset + 0) >> 3] }
  			set m00(value) { FLOAT64ARRAY[(this._offset + 0) >> 3] = value }
  			get [0]() { return FLOAT64ARRAY[(this._offset + 0) >> 3] }
  			set [0](value) { FLOAT64ARRAY[(this._offset + 0) >> 3] = value }
  			
  			get m01() { return FLOAT64ARRAY[(this._offset + 8) >> 3] }
  			set m01(value) { FLOAT64ARRAY[(this._offset + 8) >> 3] = value }
  			get [1]() { return FLOAT64ARRAY[(this._offset + 8) >> 3] }
  			set [1](value) { FLOAT64ARRAY[(this._offset + 8) >> 3] = value }
  			
  			get m02() { return FLOAT64ARRAY[(this._offset + 16) >> 3] }
  			set m02(value) { FLOAT64ARRAY[(this._offset + 16) >> 3] = value }
  			get [2]() { return FLOAT64ARRAY[(this._offset + 16) >> 3] }
  			set [2](value) { FLOAT64ARRAY[(this._offset + 16) >> 3] = value }
  			
  			get m03() { return FLOAT64ARRAY[(this._offset + 24) >> 3] }
  			set m03(value) { FLOAT64ARRAY[(this._offset + 24) >> 3] = value }
  			get [3]() { return FLOAT64ARRAY[(this._offset + 24) >> 3] }
  			set [3](value) { FLOAT64ARRAY[(this._offset + 24) >> 3] = value }
  			
  			get m10() { return FLOAT64ARRAY[(this._offset + 32) >> 3] }
  			set m10(value) { FLOAT64ARRAY[(this._offset + 32) >> 3] = value }
  			get [4]() { return FLOAT64ARRAY[(this._offset + 32) >> 3] }
  			set [4](value) { FLOAT64ARRAY[(this._offset + 32) >> 3] = value }
  			
  			get m11() { return FLOAT64ARRAY[(this._offset + 40) >> 3] }
  			set m11(value) { FLOAT64ARRAY[(this._offset + 40) >> 3] = value }
  			get [5]() { return FLOAT64ARRAY[(this._offset + 40) >> 3] }
  			set [5](value) { FLOAT64ARRAY[(this._offset + 40) >> 3] = value }
  			
  			get m12() { return FLOAT64ARRAY[(this._offset + 48) >> 3] }
  			set m12(value) { FLOAT64ARRAY[(this._offset + 48) >> 3] = value }
  			get [6]() { return FLOAT64ARRAY[(this._offset + 48) >> 3] }
  			set [6](value) { FLOAT64ARRAY[(this._offset + 48) >> 3] = value }
  			
  			get m13() { return FLOAT64ARRAY[(this._offset + 56) >> 3] }
  			set m13(value) { FLOAT64ARRAY[(this._offset + 56) >> 3] = value }
  			get [7]() { return FLOAT64ARRAY[(this._offset + 56) >> 3] }
  			set [7](value) { FLOAT64ARRAY[(this._offset + 56) >> 3] = value }
  			
  			get m20() { return FLOAT64ARRAY[(this._offset + 64) >> 3] }
  			set m20(value) { FLOAT64ARRAY[(this._offset + 64) >> 3] = value }
  			get [8]() { return FLOAT64ARRAY[(this._offset + 64) >> 3] }
  			set [8](value) { FLOAT64ARRAY[(this._offset + 64) >> 3] = value }
  			
  			get m21() { return FLOAT64ARRAY[(this._offset + 72) >> 3] }
  			set m21(value) { FLOAT64ARRAY[(this._offset + 72) >> 3] = value }
  			get [9]() { return FLOAT64ARRAY[(this._offset + 72) >> 3] }
  			set [9](value) { FLOAT64ARRAY[(this._offset + 72) >> 3] = value }
  			
  			get m22() { return FLOAT64ARRAY[(this._offset + 80) >> 3] }
  			set m22(value) { FLOAT64ARRAY[(this._offset + 80) >> 3] = value }
  			get [10]() { return FLOAT64ARRAY[(this._offset + 80) >> 3] }
  			set [10](value) { FLOAT64ARRAY[(this._offset + 80) >> 3] = value }
  			
  			get m23() { return FLOAT64ARRAY[(this._offset + 88) >> 3] }
  			set m23(value) { FLOAT64ARRAY[(this._offset + 88) >> 3] = value }
  			get [11]() { return FLOAT64ARRAY[(this._offset + 88) >> 3] }
  			set [11](value) { FLOAT64ARRAY[(this._offset + 88) >> 3] = value }
  			
  			get m30() { return FLOAT64ARRAY[(this._offset + 96) >> 3] }
  			set m30(value) { FLOAT64ARRAY[(this._offset + 96) >> 3] = value }
  			get [12]() { return FLOAT64ARRAY[(this._offset + 96) >> 3] }
  			set [12](value) { FLOAT64ARRAY[(this._offset + 96) >> 3] = value }
  			
  			get m31() { return FLOAT64ARRAY[(this._offset + 104) >> 3] }
  			set m31(value) { FLOAT64ARRAY[(this._offset + 104) >> 3] = value }
  			get [13]() { return FLOAT64ARRAY[(this._offset + 104) >> 3] }
  			set [13](value) { FLOAT64ARRAY[(this._offset + 104) >> 3] = value }
  			
  			get m32() { return FLOAT64ARRAY[(this._offset + 112) >> 3] }
  			set m32(value) { FLOAT64ARRAY[(this._offset + 112) >> 3] = value }
  			get [14]() { return FLOAT64ARRAY[(this._offset + 112) >> 3] }
  			set [14](value) { FLOAT64ARRAY[(this._offset + 112) >> 3] = value }
  			
  			get m33() { return FLOAT64ARRAY[(this._offset + 120) >> 3] }
  			set m33(value) { FLOAT64ARRAY[(this._offset + 120) >> 3] = value }
  			get [15]() { return FLOAT64ARRAY[(this._offset + 120) >> 3] }
  			set [15](value) { FLOAT64ARRAY[(this._offset + 120) >> 3] = value }
  			}
  		class _famzcj9014 { 
  			static get _size() { return 12800000 }
  			static get _align() { return undefined }
  
  			constructor(_offset_) {
  				this._offset = _offset_
  			}
  			
  			get _offset() { return this._offset_ }
  			set _offset(value) { this._offset_ = value | 0 }
  
  			get _size() { return 12800000 }
  			get _align() { return undefined }
  			
  			_fill(char) {
  				char |= 0;
  				for(let i = 0; i < 12800000; i++)
  					UINT8ARRAY[this._offset + i] = char;
  				return this
  			}
  			
  			_inc(count = 1) { this._offset += count * 12800000; return this }
  			_dec(count = 1) { this._offset -= count * 12800000; return this }
  			_next(count = 1) { return new this.constructor(this._offset + count * 12800000) }
  			_prev(count = 1) { return new this.constructor(this._offset - count * 12800000) }
  			
  			get _UINT8ARRAY() { return UINT8ARRAY }
  			get _UINT16ARRAY() { return UINT16ARRAY }
  			get _UINT32ARRAY() { return UINT32ARRAY }
  			get _INT8ARRAY() { return INT8ARRAY }
  			get _INT16ARRAY() { return INT16ARRAY }
  			get _INT32ARRAY() { return INT32ARRAY }
  			get _FLOAT32ARRAY() { return FLOAT32ARRAY }
  			get _FLOAT64ARRAY() { return FLOAT64ARRAY }
  		
  			get(index) {
  				return new _19d4rly6u4n(this._offset + index*128)
  			}
  			set(index, value) {
  				
  				const srcOffset = this._offset + index*128
  				for(let i = 0; i < 128; i++)
  					UINT8ARRAY[srcOffset + i] = value._UINT8ARRAY[value._offset + i];
  			
  			}
  			
  			[Symbol.iterator]() { return new _f0jigemxj0c(this) }
  			static get length() {return 100000}
  			get length() {return 100000}
  		}
  		class _opsiy20vorr { 
  			static get _size() { return 12800128 }
  			static get _align() { return undefined }
  
  			constructor(_offset_) {
  				this._offset = _offset_
  			}
  			
  			get _offset() { return this._offset_ }
  			set _offset(value) { this._offset_ = value | 0 }
  
  			get _size() { return 12800128 }
  			get _align() { return undefined }
  			
  			_fill(char) {
  				char |= 0;
  				for(let i = 0; i < 12800128; i++)
  					UINT8ARRAY[this._offset + i] = char;
  				return this
  			}
  			
  			_inc(count = 1) { this._offset += count * 12800128; return this }
  			_dec(count = 1) { this._offset -= count * 12800128; return this }
  			_next(count = 1) { return new this.constructor(this._offset + count * 12800128) }
  			_prev(count = 1) { return new this.constructor(this._offset - count * 12800128) }
  			
  			get _UINT8ARRAY() { return UINT8ARRAY }
  			get _UINT16ARRAY() { return UINT16ARRAY }
  			get _UINT32ARRAY() { return UINT32ARRAY }
  			get _INT8ARRAY() { return INT8ARRAY }
  			get _INT16ARRAY() { return INT16ARRAY }
  			get _INT32ARRAY() { return INT32ARRAY }
  			get _FLOAT32ARRAY() { return FLOAT32ARRAY }
  			get _FLOAT64ARRAY() { return FLOAT64ARRAY }
  		
  			get matrixTmp() { return new _19d4rly6u4n(this._offset + 0) }
  			set matrixTmp(value) { 
  				const srcOffset = this._offset + 0
  				for(let i = 0; i < 128; i++)
  					UINT8ARRAY[srcOffset + i] = value._UINT8ARRAY[value._offset + i];
  			 }
  			get [0]() { return new _19d4rly6u4n(this._offset + 0) }
  			set [0](value) { 
  				const srcOffset = this._offset + 0
  				for(let i = 0; i < 128; i++)
  					UINT8ARRAY[srcOffset + i] = value._UINT8ARRAY[value._offset + i];
  			 }
  			
  			get matrixArray() { return new _famzcj9014(this._offset + 128) }
  			set matrixArray(value) { 
  				const srcOffset = this._offset + 128
  				for(let i = 0; i < 12800000; i++)
  					UINT8ARRAY[srcOffset + i] = value._UINT8ARRAY[value._offset + i];
  			 }
  			get [1]() { return new _famzcj9014(this._offset + 128) }
  			set [1](value) { 
  				const srcOffset = this._offset + 128
  				for(let i = 0; i < 12800000; i++)
  					UINT8ARRAY[srcOffset + i] = value._UINT8ARRAY[value._offset + i];
  			 }
  			}
  		
  		
  		this.matrix4x4 = _19d4rly6u4n;
  		this.main = _opsiy20vorr;
  
  	}
  }
  /**** mat4x4 functions **/
  const glMatrix = {
  	mat4: {
  		identity(out) {
  			out[0] = 1;
  			out[1] = 0;
  			out[2] = 0;
  			out[3] = 0;
  			out[4] = 0;
  			out[5] = 1;
  			out[6] = 0;
  			out[7] = 0;
  			out[8] = 0;
  			out[9] = 0;
  			out[10] = 1;
  			out[11] = 0;
  			out[12] = 0;
  			out[13] = 0;
  			out[14] = 0;
  			out[15] = 1;
  			return out;
  		},
  		multiply(out, a, b) {
  			var a00 = a[0],
  				a01 = a[1],
  				a02 = a[2],
  				a03 = a[3];
  			var a10 = a[4],
  				a11 = a[5],
  				a12 = a[6],
  				a13 = a[7];
  			var a20 = a[8],
  				a21 = a[9],
  				a22 = a[10],
  				a23 = a[11];
  			var a30 = a[12],
  				a31 = a[13],
  				a32 = a[14],
  				a33 = a[15]; // Cache only the current line of the second matrix
  
  			var 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;
  		},
  		fromTranslation(out, v) {
  			out[0] = 1;
  			out[1] = 0;
  			out[2] = 0;
  			out[3] = 0;
  			out[4] = 0;
  			out[5] = 1;
  			out[6] = 0;
  			out[7] = 0;
  			out[8] = 0;
  			out[9] = 0;
  			out[10] = 1;
  			out[11] = 0;
  			out[12] = v[0];
  			out[13] = v[1];
  			out[14] = v[2];
  			out[15] = 1;
  			return out;
  		}
  	}
  }
  const glMatrixEx = {
  	vec3: {
  		identity(out) {
  			out.x = 0;
  			out.y = 0;
  			out.z = 0;
  		},
  		
  		transformMat4(out, a, m) {
  			var x = a.x,
  				y = a.y,
  				z = a.z;
  			var w = m[3] * x + m[7] * y + m[11] * z + m[15];
  			w = w || 1.0;
  			out.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
  			out.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
  			out.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
  			return out;
  		},
  	},
  	
  	mat4: {
  		identity(out) {
  			out.m00 = 1;
  			out.m01 = 0;
  			out.m02 = 0;
  			out.m03 = 0;
  			out.m10 = 0;
  			out.m11 = 1;
  			out.m12 = 0;
  			out.m13 = 0;
  			out.m20 = 0;
  			out.m21 = 0;
  			out.m22 = 1;
  			out.m23 = 0;
  			out.m30 = 0;
  			out.m31 = 0;
  			out.m32 = 0;
  			out.m33 = 1;
  			return out;
  		},
  		fromTranslation(out, v) {
  			out.m00 = 1;
  			out.m01 = 0;
  			out.m02 = 0;
  			out.m03 = 0;
  			out.m10 = 0;
  			out.m11 = 1;
  			out.m12 = 0;
  			out.m13 = 0;
  			out.m20 = 0;
  			out.m21 = 0;
  			out.m22 = 1;
  			out.m23 = 0;
  			out.m30 = v[0];
  			out.m31 = v[1];
  			out.m32 = v[2];
  			out.m33 = 1;
  			return out;
  		},
  
  		multiply(out, a, b) {
  			var a00 = a.m00,
  				a01 = a.m01,
  				a02 = a.m02,
  				a03 = a.m03;
  			var a10 = a.m10,
  				a11 = a.m11,
  				a12 = a.m12,
  				a13 = a.m13;
  			var a20 = a.m20,
  				a21 = a.m21,
  				a22 = a.m22,
  				a23 = a.m23;
  			var a30 = a.m30,
  				a31 = a.m31,
  				a32 = a.m32,
  				a33 = a.m33; // Cache only the current line of the second matrix
  
  			var b0 = b.m00,
  				b1 = b.m01,
  				b2 = b.m02,
  				b3 = b.m03;
  			out.m00 = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out.m01 = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out.m02 = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out.m03 = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b.m10;
  			b1 = b.m11;
  			b2 = b.m12;
  			b3 = b.m13;
  			out.m10 = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out.m11 = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out.m12 = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out.m13 = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b.m20;
  			b1 = b.m21;
  			b2 = b.m22;
  			b3 = b.m23;
  			out.m20 = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out.m21 = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out.m22 = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out.m23 = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b.m30;
  			b1 = b.m31;
  			b2 = b.m32;
  			b3 = b.m33;
  			out.m30 = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out.m31 = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out.m32 = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out.m33 = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			return out;
  		}
  	}
  	
  	
  }
  function replaceMatrixCode(code, varNames) {
  	for(const varName of varNames)
  		code = code.replace(new RegExp(varName + "\\[\\d+\\]", "g"), (s) => {
  			const [, name, index] = s.match(/(\w+)\[(\d+)\]/);
  			return `${name}.m${index / 4 | 0}${index % 4}`;
  		});
  	return code;
  }
  
  function mat4x4Multiply(out, outOffset,   a, aOffset,   b, bOffset) {
  			var a00 = a[aOffset + 0],
  				a01 = a[aOffset + 1],
  				a02 = a[aOffset + 2],
  				a03 = a[aOffset + 3];
  			var a10 = a[aOffset + 4],
  				a11 = a[aOffset + 5],
  				a12 = a[aOffset + 6],
  				a13 = a[aOffset + 7];
  			var a20 = a[aOffset + 8],
  				a21 = a[aOffset + 9],
  				a22 = a[aOffset + 10],
  				a23 = a[aOffset + 11];
  			var a30 = a[aOffset + 12],
  				a31 = a[aOffset + 13],
  				a32 = a[aOffset + 14],
  				a33 = a[aOffset + 15]; // Cache only the current line of the second matrix
  
  			var b0 = b[bOffset + 0],
  				b1 = b[bOffset + 1],
  				b2 = b[bOffset + 2],
  				b3 = b[bOffset + 3];
  			out[outOffset + 0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out[outOffset + 1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out[outOffset + 2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out[outOffset + 3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b[bOffset + 4];
  			b1 = b[bOffset + 5];
  			b2 = b[bOffset + 6];
  			b3 = b[bOffset + 7];
  			out[outOffset + 4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out[outOffset + 5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out[outOffset + 6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out[outOffset + 7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b[bOffset + 8];
  			b1 = b[bOffset + 9];
  			b2 = b[bOffset + 10];
  			b3 = b[bOffset + 11];
  			out[outOffset + 8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out[outOffset + 9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out[outOffset + 10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out[outOffset + 11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			b0 = b[bOffset + 12];
  			b1 = b[bOffset + 13];
  			b2 = b[bOffset + 14];
  			b3 = b[bOffset + 15];
  			out[outOffset + 12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  			out[outOffset + 13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  			out[outOffset + 14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  			out[outOffset + 15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  			return out;
  }
  function replaceMatrixCode2(code, varNames) {
  	for(const varName of varNames)
  		code = code.replace(new RegExp(varName + "\\[\\d+\\]", "g"), (s) => {
  			const [, name, index] = s.match(/(\w+)\[(\d+)\]/);
  			return `${name}[${name}Offset + ${index}]`;
  		});
  	return code;
  }
  /**** mat4x4 functions **/
  
  
  let HNS = 0;
  class Test {
  	constructor(translation, lastMatrix) {
  		this.translation = translation;
  		this.lastMatrix = lastMatrix;
  	}
  	
  	setMulMatrix(matrix) {
  		glMatrix.mat4.fromTranslation(matrix, this.translation);
  	}
  	
  	fetchMatrix(matrixArray, index) {
  		if ( matrixArray[index] !== undefined )
  			return matrixArray[index];
  		
  		return matrixArray.get(index);
  	}
  	tryLastMatrix(matrixArray) {
  		const matrix = this.fetchMatrix(matrixArray, matrixArray.length - 1);
  		if ( !this.lastMatrix.every((v, i) => matrix[i] === v) )
  			throw new Error(`Invalid result matrix!!!`);
  		
  		try {
  			HNS += this.fetchMatrix(matrixArray, Math.random() * matrixArray.length | 0)[ Math.random() * 16 | 0 ];
  		} catch(e) {}
  	}
  }
  class RandTests {
  	constructor(tests) {
  		this.tests = tests;
  	}
  	getRandTest() {
  		return this.tests[this.tests.length * Math.random() | 0];
  	}
  }
  const randTests = new RandTests([
  	new Test([ 78, -96, 89], [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7800000, -9600000, 8900000, 1]),
  	new Test([-13,   7, 63], [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1300000, 700000, 6300000, 1 ]),
  	new Test([-12,   3,  7], [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1200000, 300000, 700000, 1 ]),
  	new Test([ -8,  17, 37], [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -800000, 1700000, 3700000, 1 ]),
  ]);
  
  const floatArrayTpe = Float64Array//Float32Array //;
  const nativeArray = Array.from(Array(100000), () => new floatArrayTpe(16));
  const nativeNativeArray = Array.from(Array(100000), () => new Array(16));
  const float64Array = new floatArrayTpe(16*100000);
  
  const ab = new ArrayBuffer(Marshalling.main._size);
  const marshal = new Marshalling(ab);
  const main = new marshal.main(0);
  
  const tmpMatrix = new floatArrayTpe(16)//[];
  glMatrix.mat4.fromTranslation(tmpMatrix, [78, -96, 89]);
  
  /// init
  for(const matrix of nativeArray)
  	glMatrix.mat4.identity(matrix);
  
  for(const matrix of nativeNativeArray)
  	glMatrix.mat4.identity(matrix);
  
  for(const matrix of main.matrixArray)
  	glMatrixEx.mat4.identity(matrix);
  glMatrixEx.mat4.fromTranslation(main.matrixTmp, [78, -96, 89]);
  

};

Benchmark.prototype.teardown = function() {
  	
  console.log( `HNS: ${HNS}` );

};
</script>

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
Array of TypeArray
const randTest = randTests.getRandTest();
randTest.setMulMatrix(tmpMatrix);

glMatrix.mat4.identity(nativeArray[0]);
glMatrix.mat4.multiply(nativeArray[0], nativeArray[0], tmpMatrix);
for(let i = 1; i < nativeArray.length; i++)
	glMatrix.mat4.multiply(nativeArray[i], nativeArray[i-1], tmpMatrix);
randTest.tryLastMatrix(nativeArray);
pending…
Array of Array
const randTest = randTests.getRandTest();
randTest.setMulMatrix(tmpMatrix);

glMatrix.mat4.identity(nativeNativeArray[0]);
glMatrix.mat4.multiply(nativeNativeArray[0], nativeNativeArray[0], tmpMatrix);
for(let i = 1; i < nativeNativeArray.length; i++)
	glMatrix.mat4.multiply(nativeNativeArray[i], nativeNativeArray[i-1], tmpMatrix);
randTest.tryLastMatrix(nativeNativeArray);
pending…
Marshalling
const randTest = randTests.getRandTest();
randTest.setMulMatrix(main.matrixTmp);
glMatrixEx.mat4.identity(main.matrixArray.get(0));
glMatrixEx.mat4.multiply(main.matrixArray.get(0), main.matrixArray.get(0), main.matrixTmp);
for(let i = 1; i < main.matrixArray.length; i++)
	glMatrixEx.mat4.multiply(main.matrixArray.get(i), main.matrixArray.get(i-1), main.matrixTmp);
randTest.tryLastMatrix(main.matrixArray);
pending…
Vector type array
const randTest = randTests.getRandTest();
randTest.setMulMatrix(tmpMatrix);
glMatrix.mat4.identity( float64Array.subarray(0, 16) );
glMatrix.mat4.multiply( float64Array.subarray(0, 16), float64Array.subarray(0, 16), tmpMatrix);
for(let i = 1; i < 100000; i++)
	glMatrix.mat4.multiply(
		float64Array.subarray(i*16, i*16+16), 
		float64Array.subarray(i*16-16, i*16+16-16), 
		tmpMatrix
	);
randTest.tryLastMatrix([float64Array.subarray(100000*16-16, 100000*16)]);
pending…
Vector type array real
const randTest = randTests.getRandTest();
randTest.setMulMatrix(tmpMatrix);
glMatrix.mat4.identity( float64Array.subarray(0, 16) );
glMatrix.mat4.multiply( float64Array.subarray(0, 16), float64Array.subarray(0, 16), tmpMatrix);
for(let i = 16; i < 16*100000; i += 16)
	mat4x4Multiply(float64Array, i,  float64Array, i - 16, tmpMatrix, 0);
randTest.tryLastMatrix([float64Array.subarray(100000*16-16, 100000*16)]);
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