Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

benchmark: add --runs support to run.js #55158

Merged
merged 5 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 49 additions & 36 deletions benchmark/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const cli = new CLI(`usage: ./node run.js [options] [--] <category> ...
(can be repeated)
--exclude pattern excludes scripts matching <pattern> (can be
repeated)
--runs variable=value set the amount of benchmark suite execution.
Default: 1
--set variable=value set benchmark variable (can be repeated)
--format [simple|csv] optional value that specifies the output format
test only run a single configuration from the options
Expand Down Expand Up @@ -45,8 +47,7 @@ if (format === 'csv') {
console.log('"filename", "configuration", "rate", "time"');
}

(function recursive(i) {
const filename = benchmarks[i];
async function runBenchmark(filename) {
RafaelGSS marked this conversation as resolved.
Show resolved Hide resolved
const scriptPath = path.resolve(__dirname, filename);

const args = cli.test ? ['--test'] : cli.optional.set;
Expand All @@ -63,42 +64,54 @@ if (format === 'csv') {
);
}

if (format !== 'csv') {
console.log();
console.log(filename);
}

child.on('message', (data) => {
if (data.type !== 'report') {
return;
}
// Construct configuration string, " A=a, B=b, ..."
let conf = '';
for (const key of Object.keys(data.conf)) {
if (conf !== '')
conf += ' ';
conf += `${key}=${JSON.stringify(data.conf[key])}`;
}
if (format === 'csv') {
// Escape quotes (") for correct csv formatting
conf = conf.replace(/"/g, '""');
console.log(`"${data.name}", "${conf}", ${data.rate}, ${data.time}`);
} else {
let rate = data.rate.toString().split('.');
rate[0] = rate[0].replace(/(\d)(?=(?:\d\d\d)+(?!\d))/g, '$1,');
rate = (rate[1] ? rate.join('.') : rate[0]);
console.log(`${data.name} ${conf}: ${rate}`);
}
return new Promise((resolve, reject) => {
child.on('message', (data) => {
if (data.type !== 'report') {
return;
}
// Construct configuration string, " A=a, B=b, ..."
let conf = '';
for (const key of Object.keys(data.conf)) {
if (conf !== '')
conf += ' ';
conf += `${key}=${JSON.stringify(data.conf[key])}`;
}
if (format === 'csv') {
// Escape quotes (") for correct csv formatting
conf = conf.replace(/"/g, '""');
console.log(`"${data.name}", "${conf}", ${data.rate}, ${data.time}`);
} else {
let rate = data.rate.toString().split('.');
rate[0] = rate[0].replace(/(\d)(?=(?:\d\d\d)+(?!\d))/g, '$1,');
rate = (rate[1] ? rate.join('.') : rate[0]);
console.log(`${data.name} ${conf}: ${rate}`);
}
});
child.once('error', (err) => reject(err));
child.once('close', (code) => {
if (code) {
reject(code);
} else {
resolve(code);
}
});
});
}

let runs = cli.optional.runs ?? 1;

child.once('close', (code) => {
if (code) {
process.exit(code);
async function run() {
for (let i = 0; i < benchmarks.length; ++i) {
const filename = benchmarks[i];
if (format !== 'csv') {
console.log();
console.log(filename);
}

// If there are more benchmarks execute the next
if (i + 1 < benchmarks.length) {
recursive(i + 1);
while (runs--) {
await runBenchmark(filename);
}
});
})(0);
}
}

run();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we handle a possible rejection of this fn? For any reason

Copy link
Member Author

@RafaelGSS RafaelGSS Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary, it should not 'reject' and if it rejects, the tests will fail.

10 changes: 10 additions & 0 deletions doc/contributing/writing-and-running-benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ It is possible to execute more groups by adding extra process arguments.
node benchmark/run.js assert async_hooks
```

It's also possible to execute the benchmark more than once using the
`--runs` flag.

```bash
node benchmark/run.js --runs 10 assert async_hooks
```

This command will run the benchmark files in `benchmark/assert` and `benchmark/async_hooks`
10 times each.

#### Specifying CPU Cores for Benchmarks with run.js

When using `run.js` to execute a group of benchmarks,
Expand Down
Loading