-
-
Notifications
You must be signed in to change notification settings - Fork 87
/
benchmark.js
82 lines (70 loc) · 2.32 KB
/
benchmark.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict'
const { readdirSync } = require('fs')
const { spawn } = require('child_process')
const { promisify } = require('node:util')
const sget = promisify(require('simple-get').concat)
const autocannon = require('autocannon')
const { join } = require('node:path')
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
const benchmarkDir = join(__dirname, 'benchmark')
// Keep track of spawned processes and kill if runner killed
const processes = []
process.on('SIGINT', () => {
for (const p of processes) {
p.kill('SIGKILL')
}
process.exit()
})
;(async function () {
const benchmarkFiles = readdirSync(benchmarkDir)
// don't include setup file as a benchmark
.filter((fileName) => fileName !== 'setup.js')
// sort by filename length to ensure base benchmarks run first
.sort((a, b) => a.length - b.length)
for (const benchmarkFile of benchmarkFiles) {
let benchmarkProcess
try {
// Spawn benchmark process
benchmarkProcess = spawn('node', [benchmarkFile], {
detached: true,
cwd: benchmarkDir
})
processes.push(benchmarkProcess)
// wait for `server listening` from benchmark
await Promise.race([
new Promise((resolve) => {
const stdOutCb = (d) => {
if (d.toString().includes('server listening')) {
benchmarkProcess.stdout.removeListener('data', stdOutCb)
resolve()
}
}
benchmarkProcess.stdout.on('data', stdOutCb)
}),
delay(5000).then(() => Promise.reject(new Error('timed out waiting for server listening')))
])
// fire single initial request as warmup
await sget('http://localhost:3000/')
// run autocannon
const result = await autocannon({
url: 'http://localhost:3000/',
connections: 100,
duration: 5,
pipelining: 10
})
if (result.non2xx > 0) {
throw Object.assign(new Error('Some requests did not return 200'), {
statusCodeStats: result.statusCodeStats
})
}
console.log(`${benchmarkFile}: ${result.requests.average} req/s`)
} catch (err) {
console.error(`${benchmarkFile}:`, err)
} finally {
if (benchmarkProcess) {
benchmarkProcess.kill('SIGKILL')
processes.pop()
}
}
}
})()