Skip to content
Merged
Changes from all 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
70 changes: 55 additions & 15 deletions worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,56 @@ const { Bench } = require('tinybench');
const { setTimeout: delay } = require('node:timers/promises');

const runner = {
autocannon: (opts) => {
return autocannon({
url: `http://localhost:${opts.http.serverPort}`,
autocannon: async (opts, aggregated) => {
if (!aggregated.sortKey) {
aggregated.sortKey = 'requests'
}

const url = `http://localhost:${opts.http.serverPort}`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should be the host available by config?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Possibly, yes. But, it should be handled in another PR. This PR only makes HTTP benchmarks compatible with median.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

then lets 🚀

const results = await autocannon({
url,
connections: 100,
pipelining: 1,
duration: 10 * opts.http.routes.length,
requests: opts.http.routes,
})
if (!aggregated[url]) {
aggregated[url] = [results]
} else {
aggregated[url].push(results)
}
},
tinybench: async (opts) => {
tinybench: async (opts, aggregated) => {
if (!aggregated.sortKey) {
aggregated.sortKey = 'opsSec'
}

const suite = new Bench({ time: 100 });

for (const operation of opts.operations) {
suite.add(operation.name, operation.fn);
}
await suite.warmup();
await suite.run();
const results = [];
const tasks = suite.tasks;
for (const task of tasks) {
const result = task.result
results.push({
name: task.name,
opsSec: result.hz,
samples: result.samples.length,
sd: result.sd,
variance: result.variance,
})
if (!aggregated[task.name]) {
aggregated[task.name] = [{
opsSec: result.hz,
samples: result.samples.length,
sd: result.sd,
variance: result.variance,
}]
} else {
aggregated[task.name].push({
opsSec: result.hz,
samples: result.samples.length,
sd: result.sd,
variance: result.variance,
})
}
}
return results;
},
}

Expand Down Expand Up @@ -83,6 +103,22 @@ function spawnServer(settings) {
return server;
}

function findMedian(aggregated) {
const results = []
// Select median
const sortKey = aggregated.sortKey
for (const k of Object.keys(aggregated)) {
if (k === sortKey) continue
aggregated[k].sort((a, b) => a[sortKey] > b[sortKey])
const middleIndex = Math.floor(aggregated[k].length / 2);
results.push({
name: k,
...aggregated[k][middleIndex]
})
}
return results
}

async function runBenchmark(settings) {
assert.ok(ALLOWED_BENCHMARKER.includes(settings.benchmarker), 'Invalid settings.benchmarker');

Expand All @@ -93,10 +129,14 @@ async function runBenchmark(settings) {
// TODO: replace this workaround to use IPC to know when server is up
await delay(1000);
}

const benchRunner = runner[settings.benchmarker];
const benchParser = parser[settings.benchmarker];
const results = await benchRunner(settings);

const aggregated = {};
for (let i = 0; i < 10; ++i) {
await benchRunner(settings, aggregated)
}
const results = findMedian(aggregated)
if (server) {
server.kill('SIGINT');
}
Expand Down