Skip to content

Commit 86b3621

Browse files
BridgeARtargos
authored andcommitted
benchmark: rework assert benchmarks for correctness
This reworks most assert benchmarks to provide more reliable test cases that also test more cases than before while keeping the runtime low. Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de> PR-URL: #46593 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent c786ed3 commit 86b3621

7 files changed

+123
-131
lines changed

benchmark/assert/deepequal-buffer.js

+31-11
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,47 @@ const bench = common.createBenchmark(main, {
66
n: [2e4],
77
len: [1e2, 1e3],
88
strict: [0, 1],
9-
method: ['deepEqual', 'notDeepEqual'],
9+
arrayBuffer: [0, 1],
10+
method: ['deepEqual', 'notDeepEqual', 'unequal_length'],
11+
}, {
12+
combinationFilter: (p) => {
13+
return p.strict === 1 || p.method === 'deepEqual';
14+
},
1015
});
1116

12-
function main({ len, n, method, strict }) {
13-
const data = Buffer.allocUnsafe(len + 1);
14-
const actual = Buffer.alloc(len);
15-
const expected = Buffer.alloc(len);
16-
const expectedWrong = Buffer.alloc(len + 1);
17-
data.copy(actual);
18-
data.copy(expected);
19-
data.copy(expectedWrong);
17+
function main({ len, n, method, strict, arrayBuffer }) {
18+
let actual = Buffer.alloc(len);
19+
let expected = Buffer.alloc(len + Number(method === 'unequal_length'));
20+
21+
22+
if (method === 'unequal_length') {
23+
method = 'notDeepEqual';
24+
}
25+
26+
for (let i = 0; i < len; i++) {
27+
actual.writeInt8(i % 128, i);
28+
expected.writeInt8(i % 128, i);
29+
}
30+
31+
if (method.includes('not')) {
32+
const position = Math.floor(len / 2);
33+
expected[position] = expected[position] + 1;
34+
}
2035

2136
if (strict) {
2237
method = method.replace('eep', 'eepStrict');
2338
}
39+
2440
const fn = assert[method];
25-
const value2 = method.includes('not') ? expectedWrong : expected;
41+
42+
if (arrayBuffer) {
43+
actual = actual.buffer;
44+
expected = expected.buffer;
45+
}
2646

2747
bench.start();
2848
for (let i = 0; i < n; ++i) {
29-
fn(actual, value2);
49+
fn(actual, expected);
3050
}
3151
bench.end(n);
3252
}

benchmark/assert/deepequal-object.js

+17-16
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ const common = require('../common.js');
44
const assert = require('assert');
55

66
const bench = common.createBenchmark(main, {
7-
n: [5e3],
8-
size: [1e2, 1e3, 5e4],
9-
strict: [0, 1],
7+
n: [25, 2e2, 2e3],
8+
size: [1e2, 1e3, 1e4],
9+
strict: [1],
1010
method: ['deepEqual', 'notDeepEqual'],
11+
}, {
12+
combinationFilter: (p) => {
13+
return p.size === 1e4 && p.n === 25 ||
14+
p.size === 1e3 && p.n === 2e2 ||
15+
p.size === 1e2 && p.n === 2e3;
16+
},
1117
});
1218

13-
function createObj(source, add = '') {
14-
return source.map((n) => ({
19+
function createObj(size, add = '') {
20+
return Array.from({ length: size }, (n) => ({
1521
foo: 'yarp',
1622
nope: {
1723
bar: `123${add}`,
@@ -24,22 +30,17 @@ function createObj(source, add = '') {
2430
}
2531

2632
function main({ size, n, method, strict }) {
27-
const len = Math.min(Math.ceil(n / size), 20);
28-
29-
const source = Array.apply(null, Array(size));
30-
const actual = createObj(source);
31-
const expected = createObj(source);
32-
const expectedWrong = createObj(source, '4');
33-
3433
if (strict) {
3534
method = method.replace('eep', 'eepStrict');
3635
}
3736
const fn = assert[method];
38-
const value2 = method.includes('not') ? expectedWrong : expected;
37+
38+
const actual = createObj(size);
39+
const expected = method.includes('not') ? createObj(size, '4') : createObj(size);
3940

4041
bench.start();
41-
for (let i = 0; i < len; ++i) {
42-
fn(actual, value2);
42+
for (let i = 0; i < n; ++i) {
43+
fn(actual, expected);
4344
}
44-
bench.end(len);
45+
bench.end(n);
4546
}

benchmark/assert/deepequal-prims-and-objs-big-loop.js

+51-9
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,77 @@
22
const common = require('../common.js');
33
const assert = require('assert');
44

5+
const circular = {};
6+
circular.circular = circular;
7+
const circular2 = {};
8+
circular2.circular = circular2;
9+
const notCircular = {};
10+
notCircular.circular = {};
11+
512
const primValues = {
6-
'string': 'a',
7-
'number': 1,
8-
'object': { 0: 'a' },
13+
'string': 'abcdef',
14+
'number': 1_000,
15+
'boolean': true,
16+
'object': { property: 'abcdef' },
17+
'object_other_property': { property: 'abcdef' },
18+
'array': [1, 2, 3],
19+
'set_object': new Set([[1]]),
20+
'set_simple': new Set([1, 2, 3]),
21+
'circular': circular,
22+
'empty_object': {},
23+
'regexp': /abc/i,
24+
'date': new Date(),
25+
};
26+
27+
const primValues2 = {
28+
'object': { property: 'abcdef' },
929
'array': [1, 2, 3],
30+
'set_object': new Set([[1]]),
31+
'set_simple': new Set([1, 3, 2]),
32+
'circular': circular2,
33+
'empty_object': {},
34+
'regexp': /abc/i,
35+
'date': new Date(primValues.date),
36+
};
37+
38+
const primValuesUnequal = {
39+
'string': 'abcdez',
40+
'number': 1_001,
41+
'boolean': false,
42+
'object': { property2: 'abcdef' },
43+
'array': [1, 3, 2],
44+
'set_object': new Set([[2]]),
45+
'set_simple': new Set([1, 4, 2]),
46+
'circular': notCircular,
47+
'empty_object': [],
48+
'regexp': /abc/g,
49+
'date': new Date(primValues.date.getTime() + 1),
1050
};
1151

1252
const bench = common.createBenchmark(main, {
1353
primitive: Object.keys(primValues),
14-
n: [2e4],
54+
n: [1e5],
1555
strict: [0, 1],
1656
method: ['deepEqual', 'notDeepEqual'],
57+
}, {
58+
combinationFilter: (p) => {
59+
return p.strict === 1 || p.method === 'deepEqual';
60+
},
1761
});
1862

1963
function main({ n, primitive, method, strict }) {
2064
const prim = primValues[primitive];
21-
const actual = prim;
22-
const expected = prim;
23-
const expectedWrong = 'b';
65+
const actual = primValues2[primitive] ?? prim;
66+
const expected = method.includes('not') ? primValuesUnequal[primitive] : prim;
2467

2568
if (strict) {
2669
method = method.replace('eep', 'eepStrict');
2770
}
2871
const fn = assert[method];
29-
const value2 = method.includes('not') ? expectedWrong : expected;
3072

3173
bench.start();
3274
for (let i = 0; i < n; ++i) {
33-
fn([actual], [value2]);
75+
fn(actual, expected);
3476
}
3577
bench.end(n);
3678
}

benchmark/assert/deepequal-prims-and-objs-big-array-set.js benchmark/assert/deepequal-simple-array-and-set.js

+14-28
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,10 @@ const common = require('../common.js');
44
const { deepEqual, deepStrictEqual, notDeepEqual, notDeepStrictEqual } =
55
require('assert');
66

7-
const primValues = {
8-
'string': 'a',
9-
'number': 1,
10-
'object': { 0: 'a' },
11-
'array': [1, 2, 3],
12-
};
13-
147
const bench = common.createBenchmark(main, {
15-
primitive: Object.keys(primValues),
16-
n: [25],
17-
len: [2e4],
18-
strict: [0, 1],
8+
n: [5e2],
9+
len: [1e4],
10+
strict: [1],
1911
method: [
2012
'deepEqual_Array',
2113
'notDeepEqual_Array',
@@ -32,38 +24,32 @@ function run(fn, n, actual, expected) {
3224
bench.end(n);
3325
}
3426

35-
function main({ n, len, primitive, method, strict }) {
36-
const prim = primValues[primitive];
27+
function main({ n, len, method, strict }) {
3728
const actual = [];
3829
const expected = [];
39-
const expectedWrong = [];
4030

41-
for (let x = 0; x < len; x++) {
42-
actual.push(prim);
43-
expected.push(prim);
44-
expectedWrong.push(prim);
31+
for (let i = 0; i < len; i++) {
32+
actual.push(i);
33+
expected.push(i);
34+
}
35+
if (method.includes('not')) {
36+
expected[len - 1] += 1;
4537
}
46-
expectedWrong.pop();
47-
expectedWrong.push('b');
48-
49-
// Note: primitives are only added once to a set
50-
const actualSet = new Set(actual);
51-
const expectedSet = new Set(expected);
52-
const expectedWrongSet = new Set(expectedWrong);
5338

5439
switch (method) {
5540
case 'deepEqual_Array':
5641
run(strict ? deepStrictEqual : deepEqual, n, actual, expected);
5742
break;
5843
case 'notDeepEqual_Array':
59-
run(strict ? notDeepStrictEqual : notDeepEqual, n, actual, expectedWrong);
44+
run(strict ? notDeepStrictEqual : notDeepEqual, n, actual, expected);
6045
break;
6146
case 'deepEqual_Set':
62-
run(strict ? deepStrictEqual : deepEqual, n, actualSet, expectedSet);
47+
run(strict ? deepStrictEqual : deepEqual,
48+
n, new Set(actual), new Set(expected));
6349
break;
6450
case 'notDeepEqual_Set':
6551
run(strict ? notDeepStrictEqual : notDeepEqual,
66-
n, actualSet, expectedWrongSet);
52+
n, new Set(actual), new Set(expected));
6753
break;
6854
default:
6955
throw new Error(`Unsupported method "${method}"`);

benchmark/assert/deepequal-typedarrays.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ const bench = common.createBenchmark(main, {
77
'Int8Array',
88
'Uint8Array',
99
'Float32Array',
10-
'Float64Array',
11-
'Uint8ClampedArray',
10+
'Uint32Array',
1211
],
1312
n: [5e2],
1413
strict: [0, 1],
@@ -23,21 +22,24 @@ function main({ type, n, len, method, strict }) {
2322
const clazz = global[type];
2423
const actual = new clazz(len);
2524
const expected = new clazz(len);
26-
const expectedWrong = new clazz(len);
27-
const wrongIndex = Math.floor(len / 2);
28-
expectedWrong[wrongIndex] = 123;
2925

3026
if (strict) {
3127
method = method.replace('eep', 'eepStrict');
3228
}
3329
const fn = assert[method];
34-
const value2 = method.includes('not') ? expectedWrong : expected;
30+
31+
if (method.includes('not')) {
32+
expected[Math.floor(len / 2)] = 123;
33+
}
3534

3635
bench.start();
3736
for (let i = 0; i < n; ++i) {
3837
actual[0] = i;
39-
value2[0] = i;
40-
fn(actual, value2);
38+
expected[0] = i;
39+
const pos = Math.ceil(len / 2) + 1;
40+
actual[pos] = i;
41+
expected[pos] = i;
42+
fn(actual, expected);
4143
}
4244
bench.end(n);
4345
}

benchmark/assert/ok.js

-17
This file was deleted.

benchmark/assert/throws.js

-42
This file was deleted.

0 commit comments

Comments
 (0)