From: Claudio Rodriguez Date: Thu, 17 Dec 2015 13:05:45 +0000 (-0300) Subject: assert: typed array deepequal performance fix X-Git-Tag: v4.2.5~60 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=901172a783dc02bff7d272d07463594be96be4b8;p=platform%2Fupstream%2Fnodejs.git assert: typed array deepequal performance fix assert.deepEqual: when actual and expected are typed arrays, wrap them in a new Buffer each to increase performance significantly. PR-URL: https://github.com/nodejs/node/pull/4330 Fixes: https://github.com/nodejs/node/issues/4294 Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Roman Reiss Reviewed-By: Colin Ihrig --- diff --git a/benchmark/assert/deepequal-prims-and-objs-big-array.js b/benchmark/assert/deepequal-prims-and-objs-big-array.js new file mode 100644 index 0000000..d8d2b57 --- /dev/null +++ b/benchmark/assert/deepequal-prims-and-objs-big-array.js @@ -0,0 +1,37 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + prim: [ + null, + undefined, + 'a', + 1, + true, + {0: 'a'}, + [1, 2, 3], + new Array([1, 2, 3]) + ], + n: [25] +}); + +function main(conf) { + var prim = conf.prim; + var n = +conf.n; + var primArray; + var primArrayCompare; + var x; + + primArray = new Array(); + primArrayCompare = new Array(); + for (x = 0; x < (1e5); x++) { + primArray.push(prim); + primArrayCompare.push(prim); + } + + bench.start(); + for (x = 0; x < n; x++) { + assert.deepEqual(primArray, primArrayCompare); + } + bench.end(n); +} diff --git a/benchmark/assert/deepequal-prims-and-objs-big-loop.js b/benchmark/assert/deepequal-prims-and-objs-big-loop.js new file mode 100644 index 0000000..5f0519b --- /dev/null +++ b/benchmark/assert/deepequal-prims-and-objs-big-loop.js @@ -0,0 +1,30 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + prim: [ + null, + undefined, + 'a', + 1, + true, + {0: 'a'}, + [1, 2, 3], + new Array([1, 2, 3]) + ], + n: [1e5] +}); + +function main(conf) { + var prim = conf.prim; + var n = +conf.n; + var x; + + bench.start(); + + for (x = 0; x < n; x++) { + assert.deepEqual(new Array([prim]), new Array([prim])); + } + + bench.end(n); +} diff --git a/benchmark/assert/deepequal-typedarrays.js b/benchmark/assert/deepequal-typedarrays.js new file mode 100644 index 0000000..99c1320 --- /dev/null +++ b/benchmark/assert/deepequal-typedarrays.js @@ -0,0 +1,22 @@ +'use strict'; +var common = require('../common.js'); +var assert = require('assert'); +var bench = common.createBenchmark(main, { + type: ('Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array ' + + 'Float32Array Float64Array Uint8ClampedArray').split(' '), + n: [1] +}); + +function main(conf) { + var type = conf.type; + var clazz = global[type]; + var n = +conf.n; + + bench.start(); + var actual = new clazz(n * 1e6); + var expected = new clazz(n * 1e6); + + assert.deepEqual(actual, expected); + + bench.end(n); +} diff --git a/lib/assert.js b/lib/assert.js index 6b99098..f8dc97d 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -170,6 +170,11 @@ function _deepEqual(actual, expected, strict) { (expected === null || typeof expected !== 'object')) { return strict ? actual === expected : actual == expected; + // If both values are instances of typed arrays, wrap them in + // a Buffer each to increase performance + } else if (ArrayBuffer.isView(actual) && ArrayBuffer.isView(expected)) { + return compare(new Buffer(actual), new Buffer(expected)) === 0; + // 7.5 For all other Object pairs, including Array objects, equivalence is // determined by having the same number of owned properties (as verified // with Object.prototype.hasOwnProperty.call), the same set of keys diff --git a/test/parallel/test-assert-typedarray-deepequal.js b/test/parallel/test-assert-typedarray-deepequal.js new file mode 100644 index 0000000..3274878 --- /dev/null +++ b/test/parallel/test-assert-typedarray-deepequal.js @@ -0,0 +1,41 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const a = require('assert'); + +function makeBlock(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return f.apply(this, args); + }; +} + +const equalArrayPairs = [ + [new Uint8Array(1e5), new Uint8Array(1e5)], + [new Uint16Array(1e5), new Uint16Array(1e5)], + [new Uint32Array(1e5), new Uint32Array(1e5)], + [new Uint8ClampedArray(1e5), new Uint8ClampedArray(1e5)], + [new Int8Array(1e5), new Int8Array(1e5)], + [new Int16Array(1e5), new Int16Array(1e5)], + [new Int32Array(1e5), new Int32Array(1e5)], + [new Float32Array(1e5), new Float32Array(1e5)], + [new Float64Array(1e5), new Float64Array(1e5)] +]; + +const notEqualArrayPairs = [ + [new Uint8Array(2), new Uint8Array(3)], + [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])], + [new Uint8ClampedArray([300, 2, 3]), new Uint8Array([300, 2, 3])] +]; + +equalArrayPairs.forEach((arrayPair) => { + assert.deepEqual(arrayPair[0], arrayPair[1]); +}); + +notEqualArrayPairs.forEach((arrayPair) => { + assert.throws( + makeBlock(a.deepEqual, arrayPair[0], arrayPair[1]), + a.AssertionError + ); +});