forked from ekino/node-logger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.js
97 lines (86 loc) · 2.95 KB
/
utils.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
import * as logger2 from '@ekino/logger'
import { Suite } from '@jonahsnider/benchmark'
import pino from 'pino'
import * as winston from 'winston'
import * as logger3 from '../lib/esm/index.js'
/**
* Initializes loggers for benchmarking.
*/
export const initializeLoggers = () => {
logger2.setLevel('info')
logger3.setLevel('info')
return {
ekinoLoggerV2: logger2.createLogger('benchmark'),
ekinoLoggerV3: logger3.createLogger('benchmark'),
pinoLogger: pino({
level: 'info',
prettyPrint: false,
destination: pino.destination({ sync: true }),
}),
winstonLogger: winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [new winston.transports.Console()],
}),
}
}
/**
* Sets up the benchmark suite.
* @param {string} name Name of the benchmark suite
*/
export const createBenchmarkSuite = (name) => {
return new Suite(name, {
warmup: { trials: 3000 },
run: { trials: 10_000 },
})
}
/**
* Generates a nested object for complex benchmarks.
* @param {number} numKeys Number of keys in each object
* @param {number} depth Depth of the nested object
* @param {number} [currentDepth=1] Current depth of the object
*/
export const generateNestedObject = (numKeys, depth, currentDepth = 1) => {
if (currentDepth > depth) return null
const obj = {}
for (let i = 0; i < numKeys; i++) {
const key = `key_${currentDepth}_${i}`
obj[key] =
currentDepth === depth
? {
stringValue: `string_${currentDepth}_${i}`,
numberValue: i * 10,
boolValue: i % 2 === 0,
arrayValue: Array.from({ length: 3 }, (_, j) => `arrayItem_${j}`),
}
: generateNestedObject(numKeys, depth, currentDepth + 1)
}
return obj
}
/**
* Formats benchmark results into a console table.
* @param {Array<[string, import('@ekino/logger').Histogram]>} results
*/
export const formatResultsTable = (results) => {
return [...results]
.map(([library, histogram]) => [library, Math.round(1e9 / histogram.percentile(50))])
.sort(([, a], [, b]) => b - a)
.map(([library, opsPerSec]) => ({
library,
'ops/sec': opsPerSec.toLocaleString(),
}))
}
/**
* Runs the benchmark suite and displays results after a dynamic timeout.
* @param {Suite} suite Benchmark suite instance
* @param {number} timeout Timeout value in milliseconds
*/
export const runSuiteWithDynamicTimeout = async (suite, timeout = 1000) => {
const startTime = performance.now()
const results = await suite.run()
const endTime = performance.now()
const executionTime = endTime - startTime
const timeoutValue = executionTime + timeout
const table = formatResultsTable(results)
setTimeout(() => console.table(table), timeoutValue)
}