11'use strict' ;
22
33const { spawn, fork } = require ( 'node:child_process' ) ;
4+ const { closeSync, openSync, writeSync } = require ( 'node:fs' ) ;
45const { inspect } = require ( 'util' ) ;
56const path = require ( 'path' ) ;
67const CLI = require ( './_cli.js' ) ;
@@ -27,7 +28,9 @@ const cli = new CLI(`usage: ./node compare.js [options] [--] <category> ...
2728 --no-progress don't show benchmark progress indicator
2829 --analyze perform statistical analysis after benchmarks
2930 complete (Welch's t-test, effect size) instead
30- of printing csv output
31+ of printing csv output to stdout
32+ --csv filename write csv output to filename (can be combined
33+ with --analyze)
3134 --scale 1000 rate-to-integer multiplier for histogram
3235 precision when using --analyze (default: 1000)
3336 --max-regression N exit with code 1 if any statistically
@@ -60,6 +63,19 @@ if (benchmarks.length === 0) {
6063 return ;
6164}
6265
66+ const csvFd = cli . optional . csv === undefined ?
67+ null :
68+ openSync ( cli . optional . csv , 'w' ) ;
69+ const outputCsv = ! analyze || csvFd !== null ;
70+
71+ function writeCsv ( line ) {
72+ if ( csvFd === null ) {
73+ console . log ( line ) ;
74+ } else {
75+ writeSync ( csvFd , `${ line } \n` ) ;
76+ }
77+ }
78+
6379// When --analyze is set, collect results for statistical analysis.
6480const results = analyze ? new Map ( ) : null ;
6581
@@ -78,17 +94,19 @@ for (const filename of benchmarks) {
7894}
7995// queue.length = binary.length * runs * benchmarks.length
8096
81- // Print csv header ( unless analyzing inline) .
82- if ( ! analyze ) {
83- console . log ( '"binary","filename","configuration","rate","time"' ) ;
97+ // Print csv header unless only analyzing inline.
98+ if ( outputCsv ) {
99+ writeCsv ( '"binary","filename","configuration","rate","time"' ) ;
84100}
85101
86102const kStartOfQueue = 0 ;
87103
88104const showProgress = ! cli . optional [ 'no-progress' ] ;
89105let progress ;
90106if ( showProgress ) {
91- progress = new BenchmarkProgress ( queue , benchmarks , { analyze } ) ;
107+ progress = new BenchmarkProgress ( queue , benchmarks , {
108+ analyze : analyze || csvFd !== null ,
109+ } ) ;
92110 progress . startQueue ( kStartOfQueue ) ;
93111}
94112
@@ -126,11 +144,13 @@ if (showProgress) {
126144 results . set ( name , { old : [ ] , new : [ ] } ) ;
127145 }
128146 results . get ( name ) [ job . binary ] . push ( data . rate ) ;
129- } else {
147+ }
148+
149+ if ( outputCsv ) {
130150 // Escape quotes (") for correct csv formatting
131- conf = conf . replace ( / " / g, '""' ) ;
132- console . log ( `"${ job . binary } ","${ job . filename } ","${ conf } ",` +
133- `${ data . rate } ,${ data . time } ` ) ;
151+ const csvConf = conf . replace ( / " / g, '""' ) ;
152+ writeCsv ( `"${ job . binary } ","${ job . filename } ","${ csvConf } ",` +
153+ `${ data . rate } ,${ data . time } ` ) ;
134154 }
135155 if ( showProgress ) {
136156 // One item in the subqueue has been completed.
@@ -153,8 +173,9 @@ if (showProgress) {
153173 // If there are more benchmarks execute the next
154174 if ( i + 1 < queue . length ) {
155175 recursive ( i + 1 ) ;
156- } else if ( analyze ) {
157- printAnalysis ( results , scale , maxRegression ) ;
176+ } else {
177+ if ( csvFd !== null ) closeSync ( csvFd ) ;
178+ if ( analyze ) printAnalysis ( results , scale , maxRegression ) ;
158179 }
159180 } ) ;
160181} ) ( kStartOfQueue ) ;
0 commit comments