From 7c0cc12f0bab5a7eb7b4ed1f08d9b4196a06b66e Mon Sep 17 00:00:00 2001 From: Rafael Gonzaga Date: Fri, 18 Oct 2024 12:33:58 -0300 Subject: [PATCH] benchmark: add --runs support to run.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55158 Reviewed-By: Vinícius Lourenço Claro Cardoso --- benchmark/run.js | 89 +++++++++++-------- .../writing-and-running-benchmarks.md | 10 +++ 2 files changed, 60 insertions(+), 39 deletions(-) diff --git a/benchmark/run.js b/benchmark/run.js index 6a61df71221..ea0dc415e91 100644 --- a/benchmark/run.js +++ b/benchmark/run.js @@ -12,6 +12,8 @@ const cli = new CLI(`usage: ./node run.js [options] [--] ... (can be repeated) --exclude pattern excludes scripts matching (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 @@ -45,8 +47,7 @@ if (format === 'csv') { console.log('"filename", "configuration", "rate", "time"'); } -(function recursive(i) { - const filename = benchmarks[i]; +function runBenchmark(filename) { const scriptPath = path.resolve(__dirname, filename); const args = cli.test ? ['--test'] : cli.optional.set; @@ -63,42 +64,52 @@ if (format === 'csv') { ); } - if (format !== 'csv') { - console.log(); - console.log(filename); + 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('close', (code) => { + if (code) { + reject(code); + } else { + resolve(code); + } + }); + }); +} + +async function run() { + for (let i = 0; i < benchmarks.length; ++i) { + let runs = cli.optional.runs ?? 1; + const filename = benchmarks[i]; + if (format !== 'csv') { + console.log(); + console.log(filename); + } + + while (runs-- > 0) { + await runBenchmark(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}`); - } - }); - - child.once('close', (code) => { - if (code) { - process.exit(code); - } - - // If there are more benchmarks execute the next - if (i + 1 < benchmarks.length) { - recursive(i + 1); - } - }); -})(0); +run(); diff --git a/doc/contributing/writing-and-running-benchmarks.md b/doc/contributing/writing-and-running-benchmarks.md index c258280ce95..3d16c7d14fc 100644 --- a/doc/contributing/writing-and-running-benchmarks.md +++ b/doc/contributing/writing-and-running-benchmarks.md @@ -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,