-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathbenchmark.js
114 lines (96 loc) · 2.56 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// @ts-check
import { performance } from 'node:perf_hooks'
import { fileURLToPath } from 'node:url'
const RUN_TIMES = +(process.env.RUN_TIMES || 1000)
const __filename = fileURLToPath(import.meta.url)
/**
* @param {string} name
* @typedef {{ loadTime: number, runTime: number, totalTime: number } | void} PerfResult
* @returns {Promise<PerfResult>} Perf result
*/
const perfCase = async name => {
const loadStartTime = performance.now()
let syncFn
try {
;({ default: syncFn } = await import(
`./${name}.${
name === 'synckit' || name === 'make-synchronized' ? 'js' : 'cjs'
}`
))
} catch {
return
}
const loadTime = performance.now() - loadStartTime
let i = RUN_TIMES
const runStartTime = performance.now()
while (i-- > 0) {
syncFn(__filename)
}
const runTime = performance.now() - runStartTime
return {
loadTime,
runTime,
totalTime: runTime + loadTime,
}
}
/**
* @param {string} text
* @returns {string} Kebab cased text
*/
const kebabCase = text =>
text.replace(/([A-Z]+)/, (_, $1) => '-' + $1.toLowerCase())
class Benchmark {
/**
* @param { Record.<string, PerfResult> } perfResults
*/
constructor(perfResults) {
const keys = Object.keys(perfResults)
const _baseKey = keys[0]
const baseKey = kebabCase(_baseKey)
const perfTypes = /** @type {const} */ ([
'loadTime',
'runTime',
'totalTime',
])
for (const perfType of perfTypes) {
const basePerf = perfResults[_baseKey]?.[perfType]
this[perfType] = keys.reduce((acc, key) => {
const perfResult = perfResults[key]
const perfTime = perfResult?.[perfType]
key = kebabCase(key)
return Object.assign(acc, {
[key]: perfTime == null ? 'N/A' : perfTime.toFixed(2) + 'ms',
...(key === baseKey
? null
: {
[`perf ${key}`]:
basePerf == null || perfTime == null
? 'N/A'
: this.perf(basePerf, perfTime),
}),
})
}, {})
}
}
/**
* @param {number} a
* @param {number} b
* @returns {string} perf description
*/
perf(a, b) {
return a === b
? 'same'
: a > b
? (a / b).toFixed(2) + 'x slower'
: (b / a).toFixed(2) + 'x faster'
}
}
console.table(
new Benchmark({
synckit: await perfCase('synckit'),
syncThreads: await perfCase('sync-threads'),
deasync: await perfCase('deasync'),
makeSynchronized: await perfCase('make-synchronized'),
native: await perfCase('native'),
}),
)