Skip to content

Commit 1760c23

Browse files
committed
benchmark: add test and all options and improve errors"
This reverts commit 4671d55 and contains a fix to the issue raised for the revert. PR-URL: #31755 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent f64aafa commit 1760c23

38 files changed

+305
-200
lines changed

benchmark/_cli.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,24 @@ const path = require('path');
66
// Create an object of all benchmark scripts
77
const benchmarks = {};
88
fs.readdirSync(__dirname)
9-
.filter((name) => fs.statSync(path.resolve(__dirname, name)).isDirectory())
9+
.filter((name) => {
10+
return name !== 'fixtures' &&
11+
fs.statSync(path.resolve(__dirname, name)).isDirectory();
12+
})
1013
.forEach((category) => {
1114
benchmarks[category] = fs.readdirSync(path.resolve(__dirname, category))
1215
.filter((filename) => filename[0] !== '.' && filename[0] !== '_');
1316
});
1417

1518
function CLI(usage, settings) {
16-
if (!(this instanceof CLI)) return new CLI(usage, settings);
17-
1819
if (process.argv.length < 3) {
1920
this.abort(usage); // Abort will exit the process
2021
}
2122

2223
this.usage = usage;
2324
this.optional = {};
2425
this.items = [];
26+
this.test = false;
2527

2628
for (const argName of settings.arrayArgs) {
2729
this.optional[argName] = [];
@@ -34,7 +36,7 @@ function CLI(usage, settings) {
3436
if (arg === '--') {
3537
// Only items can follow --
3638
mode = 'item';
37-
} else if ('both' === mode && arg[0] === '-') {
39+
} else if (mode === 'both' && arg[0] === '-') {
3840
// Optional arguments declaration
3941

4042
if (arg[1] === '-') {
@@ -61,6 +63,8 @@ function CLI(usage, settings) {
6163

6264
// The next value can be either an option or an item
6365
mode = 'both';
66+
} else if (arg === 'test') {
67+
this.test = true;
6468
} else if (['both', 'item'].includes(mode)) {
6569
// item arguments
6670
this.items.push(arg);
@@ -83,9 +87,15 @@ CLI.prototype.abort = function(msg) {
8387
CLI.prototype.benchmarks = function() {
8488
const paths = [];
8589

90+
if (this.items.includes('all')) {
91+
this.items = Object.keys(benchmarks);
92+
}
93+
8694
for (const category of this.items) {
87-
if (benchmarks[category] === undefined)
88-
continue;
95+
if (benchmarks[category] === undefined) {
96+
console.error(`The "${category}" category does not exist.`);
97+
process.exit(1);
98+
}
8999
for (const scripts of benchmarks[category]) {
90100
if (this.shouldSkip(scripts)) continue;
91101

benchmark/_http-benchmarkers.js

+19-13
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ class AutocannonBenchmarker {
4343
}
4444
if (!result || !result.requests || !result.requests.average) {
4545
return undefined;
46-
} else {
47-
return result.requests.average;
4846
}
47+
return result.requests.average;
4948
}
5049
}
5150

@@ -58,10 +57,13 @@ class WrkBenchmarker {
5857
}
5958

6059
create(options) {
60+
const duration = typeof options.duration === 'number' ?
61+
Math.max(options.duration, 1) :
62+
options.duration;
6163
const args = [
62-
'-d', options.duration,
64+
'-d', duration,
6365
'-c', options.connections,
64-
'-t', 8,
66+
'-t', Math.min(options.connections, require('os').cpus().length || 8),
6567
`http://127.0.0.1:${options.port}${options.path}`,
6668
];
6769
for (const field in options.headers) {
@@ -77,9 +79,8 @@ class WrkBenchmarker {
7779
const throughput = match && +match[1];
7880
if (!isFinite(throughput)) {
7981
return undefined;
80-
} else {
81-
return throughput;
8282
}
83+
return throughput;
8384
}
8485
}
8586

@@ -89,18 +90,21 @@ class WrkBenchmarker {
8990
*/
9091
class TestDoubleBenchmarker {
9192
constructor(type) {
92-
// `type` is the type ofbenchmarker. Possible values are 'http' and 'http2'.
93+
// `type` is the type of benchmarker. Possible values are 'http' and
94+
// 'http2'.
9395
this.name = `test-double-${type}`;
9496
this.executable = path.resolve(__dirname, '_test-double-benchmarker.js');
9597
this.present = fs.existsSync(this.executable);
9698
this.type = type;
9799
}
98100

99101
create(options) {
100-
const env = Object.assign({
101-
duration: options.duration,
102+
process.env.duration = process.env.duration || options.duration || 5;
103+
104+
const env = {
102105
test_url: `http://127.0.0.1:${options.port}${options.path}`,
103-
}, process.env);
106+
...process.env
107+
};
104108

105109
const child = child_process.fork(this.executable,
106110
[this.type],
@@ -189,13 +193,14 @@ http_benchmarkers.forEach((benchmarker) => {
189193
});
190194

191195
exports.run = function(options, callback) {
192-
options = Object.assign({
196+
options = {
193197
port: exports.PORT,
194198
path: '/',
195199
connections: 100,
196200
duration: 5,
197201
benchmarker: exports.default_http_benchmarker,
198-
}, options);
202+
...options
203+
};
199204
if (!options.benchmarker) {
200205
callback(new Error('Could not locate required http benchmarker. See ' +
201206
`${requirementsURL} for further instructions.`));
@@ -220,7 +225,8 @@ exports.run = function(options, callback) {
220225
child.stderr.pipe(process.stderr);
221226

222227
let stdout = '';
223-
child.stdout.on('data', (chunk) => stdout += chunk.toString());
228+
child.stdout.setEncoding('utf8');
229+
child.stdout.on('data', (chunk) => stdout += chunk);
224230

225231
child.once('close', (code) => {
226232
const elapsed = process.hrtime(benchmarker_start);

benchmark/_test-double-benchmarker.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!['http', 'http2'].includes(myModule)) {
77

88
const http = require(myModule);
99

10-
const duration = process.env.duration || 0;
10+
const duration = +process.env.duration;
1111
const url = process.env.test_url;
1212

1313
const start = process.hrtime();
@@ -18,13 +18,15 @@ function request(res, client) {
1818
res.on('error', () => {});
1919
res.on('end', () => {
2020
throughput++;
21-
const diff = process.hrtime(start);
22-
if (duration > 0 && diff[0] < duration) {
21+
const [sec, nanosec] = process.hrtime(start);
22+
const ms = sec * 1000 + nanosec / 1e6;
23+
if (ms < duration * 1000) {
2324
run();
2425
} else {
2526
console.log(JSON.stringify({ throughput }));
2627
if (client) {
2728
client.destroy();
29+
process.exit(0);
2830
}
2931
}
3032
});
@@ -33,7 +35,7 @@ function request(res, client) {
3335
function run() {
3436
if (http.get) { // HTTP
3537
http.get(url, request);
36-
} else { // HTTP/2
38+
} else { // HTTP/2
3739
const client = http.connect(url);
3840
client.on('error', (e) => { throw e; });
3941
request(client.request(), client);

benchmark/async_hooks/async-resource-vs-destroy.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@ const {
1313
} = require('async_hooks');
1414
const { createServer } = require('http');
1515

16-
// Configuration for the http server
17-
// there is no need for parameters in this test
18-
const connections = 500;
19-
const path = '/';
20-
2116
const bench = common.createBenchmark(main, {
2217
type: ['async-resource', 'destroy', 'async-local-storage'],
2318
asyncMethod: ['callbacks', 'async'],
19+
path: '/',
20+
connections: 500,
21+
duration: 5,
2422
n: [1e6]
2523
});
2624

@@ -165,7 +163,7 @@ const asyncMethods = {
165163
'async': getServeAwait
166164
};
167165

168-
function main({ type, asyncMethod }) {
166+
function main({ type, asyncMethod, connections, duration, path }) {
169167
const { server, close } = types[type](asyncMethods[asyncMethod]);
170168

171169
server
@@ -174,7 +172,8 @@ function main({ type, asyncMethod }) {
174172

175173
bench.http({
176174
path,
177-
connections
175+
connections,
176+
duration
178177
}, () => {
179178
close();
180179
});

benchmark/async_hooks/http-server.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ const common = require('../common.js');
33

44
const bench = common.createBenchmark(main, {
55
asyncHooks: ['init', 'before', 'after', 'all', 'disabled', 'none'],
6-
connections: [50, 500]
6+
connections: [50, 500],
7+
duration: 5
78
});
89

9-
function main({ asyncHooks, connections }) {
10+
function main({ asyncHooks, connections, duration }) {
1011
if (asyncHooks !== 'none') {
1112
let hooks = {
1213
init() {},
@@ -33,6 +34,7 @@ function main({ asyncHooks, connections }) {
3334
bench.http({
3435
connections,
3536
path,
37+
duration
3638
}, () => {
3739
server.close();
3840
});

benchmark/buffers/buffer-base64-encode.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const common = require('../common.js');
2525
const bench = common.createBenchmark(main, {
2626
len: [64 * 1024 * 1024],
2727
n: [32]
28+
}, {
29+
test: { len: 256 }
2830
});
2931

3032
function main({ n, len }) {

benchmark/buffers/buffer-swap.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const bench = common.createBenchmark(main, {
77
method: ['swap16', 'swap32', 'swap64'/* , 'htons', 'htonl', 'htonll' */],
88
len: [64, 256, 768, 1024, 2056, 8192],
99
n: [1e6]
10+
}, {
11+
test: { len: 16 }
1012
});
1113

1214
// The htons and htonl methods below are used to benchmark the

0 commit comments

Comments
 (0)