@@ -7,36 +7,56 @@ const { Bench } = require('tinybench');
77const { setTimeout : delay } = require ( 'node:timers/promises' ) ;
88
99const runner = {
10- autocannon : ( opts ) => {
11- return autocannon ( {
12- url : `http://localhost:${ opts . http . serverPort } ` ,
10+ autocannon : async ( opts , aggregated ) => {
11+ if ( ! aggregated . sortKey ) {
12+ aggregated . sortKey = 'requests'
13+ }
14+
15+ const url = `http://localhost:${ opts . http . serverPort } `
16+ const results = await autocannon ( {
17+ url,
1318 connections : 100 ,
1419 pipelining : 1 ,
1520 duration : 10 * opts . http . routes . length ,
1621 requests : opts . http . routes ,
1722 } )
23+ if ( ! aggregated [ url ] ) {
24+ aggregated [ url ] = [ results ]
25+ } else {
26+ aggregated [ url ] . push ( results )
27+ }
1828 } ,
19- tinybench : async ( opts ) => {
29+ tinybench : async ( opts , aggregated ) => {
30+ if ( ! aggregated . sortKey ) {
31+ aggregated . sortKey = 'opsSec'
32+ }
33+
2034 const suite = new Bench ( { time : 100 } ) ;
2135
2236 for ( const operation of opts . operations ) {
2337 suite . add ( operation . name , operation . fn ) ;
2438 }
2539 await suite . warmup ( ) ;
2640 await suite . run ( ) ;
27- const results = [ ] ;
2841 const tasks = suite . tasks ;
2942 for ( const task of tasks ) {
3043 const result = task . result
31- results . push ( {
32- name : task . name ,
33- opsSec : result . hz ,
34- samples : result . samples . length ,
35- sd : result . sd ,
36- variance : result . variance ,
37- } )
44+ if ( ! aggregated [ task . name ] ) {
45+ aggregated [ task . name ] = [ {
46+ opsSec : result . hz ,
47+ samples : result . samples . length ,
48+ sd : result . sd ,
49+ variance : result . variance ,
50+ } ]
51+ } else {
52+ aggregated [ task . name ] . push ( {
53+ opsSec : result . hz ,
54+ samples : result . samples . length ,
55+ sd : result . sd ,
56+ variance : result . variance ,
57+ } )
58+ }
3859 }
39- return results ;
4060 } ,
4161}
4262
@@ -83,6 +103,22 @@ function spawnServer(settings) {
83103 return server ;
84104}
85105
106+ function findMedian ( aggregated ) {
107+ const results = [ ]
108+ // Select median
109+ const sortKey = aggregated . sortKey
110+ for ( const k of Object . keys ( aggregated ) ) {
111+ if ( k === sortKey ) continue
112+ aggregated [ k ] . sort ( ( a , b ) => a [ sortKey ] > b [ sortKey ] )
113+ const middleIndex = Math . floor ( aggregated [ k ] . length / 2 ) ;
114+ results . push ( {
115+ name : k ,
116+ ...aggregated [ k ] [ middleIndex ]
117+ } )
118+ }
119+ return results
120+ }
121+
86122async function runBenchmark ( settings ) {
87123 assert . ok ( ALLOWED_BENCHMARKER . includes ( settings . benchmarker ) , 'Invalid settings.benchmarker' ) ;
88124
@@ -93,10 +129,14 @@ async function runBenchmark(settings) {
93129 // TODO: replace this workaround to use IPC to know when server is up
94130 await delay ( 1000 ) ;
95131 }
96-
97132 const benchRunner = runner [ settings . benchmarker ] ;
98133 const benchParser = parser [ settings . benchmarker ] ;
99- const results = await benchRunner ( settings ) ;
134+
135+ const aggregated = { } ;
136+ for ( let i = 0 ; i < 10 ; ++ i ) {
137+ await benchRunner ( settings , aggregated )
138+ }
139+ const results = findMedian ( aggregated )
100140 if ( server ) {
101141 server . kill ( 'SIGINT' ) ;
102142 }
0 commit comments