Skip to content

Commit cddeca5

Browse files
committed
feat: use median as attempt to avoid outliers
1 parent 2390978 commit cddeca5

File tree

1 file changed

+55
-15
lines changed

1 file changed

+55
-15
lines changed

worker.js

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,56 @@ const { Bench } = require('tinybench');
77
const { setTimeout: delay } = require('node:timers/promises');
88

99
const 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+
86122
async 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

Comments
 (0)