Skip to content

Commit 1444870

Browse files
committed
bench: add websockets
1 parent 69cfd97 commit 1444870

File tree

9 files changed

+849
-1
lines changed

9 files changed

+849
-1
lines changed

benchmarks/_util/runner.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// @ts-check
2+
3+
'use strict'
4+
5+
class Info {
6+
/** @type {string} */
7+
#name
8+
/** @type {bigint} */
9+
#current
10+
/** @type {bigint} */
11+
#finish
12+
/** @type {(...args: any[]) => any} */
13+
#callback
14+
/** @type {boolean} */
15+
#finalized = false
16+
17+
/**
18+
* @param {string} name
19+
* @param {(...args: any[]) => any} callback
20+
*/
21+
constructor (name, callback) {
22+
this.#name = name
23+
this.#callback = callback
24+
}
25+
26+
get name () {
27+
return this.#name
28+
}
29+
30+
start () {
31+
if (this.#finalized) {
32+
throw new TypeError('called after finished.')
33+
}
34+
this.#current = process.hrtime.bigint()
35+
}
36+
37+
end () {
38+
if (this.#finalized) {
39+
throw new TypeError('called after finished.')
40+
}
41+
this.#finish = process.hrtime.bigint()
42+
this.#finalized = true
43+
this.#callback()
44+
}
45+
46+
diff () {
47+
return Number(this.#finish - this.#current)
48+
}
49+
}
50+
51+
/**
52+
* @typedef BenchMarkHandler
53+
* @type {(ev: { name: string; start(): void; end(): void; }) => any}
54+
*/
55+
56+
/**
57+
* @param {Record<string, BenchMarkHandler>} experiments
58+
* @param {{}} [options]
59+
* @returns {Promise<{ name: string; average: number; samples: number; fn: BenchMarkHandler; min: number; max: number }[]>}
60+
*/
61+
async function bench (experiments, options = {}) {
62+
const names = Object.keys(experiments)
63+
64+
/** @type {{ name: string; average: number; samples: number; fn: BenchMarkHandler; min: number; max: number }[]} */
65+
const results = []
66+
67+
async function waitMaybePromiseLike (p) {
68+
if (
69+
(typeof p === 'object' || typeof p === 'function') &&
70+
p !== null &&
71+
typeof p.then === 'function'
72+
) {
73+
await p
74+
}
75+
}
76+
77+
for (let i = 0; i < names.length; ++i) {
78+
const name = names[i]
79+
const fn = experiments[name]
80+
const samples = []
81+
82+
let timing = 0
83+
84+
for (let j = 0; j < 128 || timing < 800_000_000; ++j) {
85+
let resolve = (value) => {}
86+
let reject = (reason) => {}
87+
const promise = new Promise(
88+
(_resolve, _reject) => { resolve = _resolve; reject = _reject }
89+
)
90+
91+
const info = new Info(name, resolve)
92+
93+
try {
94+
const p = fn(info)
95+
96+
await waitMaybePromiseLike(p)
97+
} catch (err) {
98+
reject(err)
99+
}
100+
101+
await promise
102+
103+
samples.push({ time: info.diff() })
104+
105+
timing += info.diff()
106+
}
107+
108+
const average =
109+
samples.map((v) => v.time).reduce((a, b) => a + b, 0) / samples.length
110+
111+
results.push({
112+
name: names[i],
113+
average,
114+
samples: samples.length,
115+
fn,
116+
min: samples.reduce((a, acc) => Math.min(a, acc.time), samples[0].time),
117+
max: samples.reduce((a, acc) => Math.max(a, acc.time), samples[0].time)
118+
})
119+
}
120+
121+
return results
122+
}
123+
124+
module.exports = { bench }

0 commit comments

Comments
 (0)