@indutny/bencher 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/bencher.js +48 -10
- package/package.json +1 -1
package/dist/bin/bencher.js
CHANGED
|
@@ -30,6 +30,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
const promises_1 = require("fs/promises");
|
|
31
31
|
const yargs_1 = __importDefault(require("yargs"));
|
|
32
32
|
const helpers_1 = require("yargs/helpers");
|
|
33
|
+
// ANSI colors
|
|
34
|
+
const BOLD = 1;
|
|
35
|
+
const ITALIC = 3;
|
|
36
|
+
// Go back to previous line, clear the line
|
|
37
|
+
const PREV_LINE = '\x1b[F\x1b[K';
|
|
38
|
+
// t-distribution value for large sample count and p=0.001
|
|
39
|
+
// https://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
|
|
40
|
+
const STUDENT_T = 3.09;
|
|
41
|
+
const P_VALUE = 0.001;
|
|
33
42
|
async function main() {
|
|
34
43
|
const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
35
44
|
.alias('h', 'help')
|
|
@@ -87,26 +96,47 @@ async function main() {
|
|
|
87
96
|
default: m.default,
|
|
88
97
|
};
|
|
89
98
|
}));
|
|
99
|
+
const maxNameLength = modules.reduce((len, { name }) => Math.max(len, name.length), 0);
|
|
90
100
|
for (const m of modules) {
|
|
91
|
-
|
|
101
|
+
const paddedName = style(m.name, BOLD) + ':' + ' '.repeat(maxNameLength - m.name.length);
|
|
102
|
+
// Just to reserve the line
|
|
103
|
+
process.stdout.write('\n');
|
|
104
|
+
let ticks = 0;
|
|
105
|
+
const onTick = () => {
|
|
106
|
+
process.stdout.write(`${PREV_LINE}${paddedName} ${'.'.repeat(ticks)}\n`);
|
|
107
|
+
ticks = 1 + (ticks % 3);
|
|
108
|
+
};
|
|
109
|
+
onTick();
|
|
110
|
+
const { ops, maxError, usedSamples } = run(m, {
|
|
111
|
+
onTick,
|
|
112
|
+
});
|
|
113
|
+
const stats = style(`(±${nice(maxError)}, p=${P_VALUE}, n=${usedSamples})`, ITALIC);
|
|
114
|
+
process.stdout.write(`${PREV_LINE}${paddedName} ${nice(ops)} ops/sec ${stats}\n`);
|
|
92
115
|
}
|
|
93
116
|
}
|
|
94
|
-
function run(m) {
|
|
117
|
+
function run(m, { onTick }) {
|
|
95
118
|
const baseIterations = warmUp(m);
|
|
96
119
|
const samples = new Array();
|
|
120
|
+
const tickEvery = Math.round(m.options.samples / m.options.duration);
|
|
97
121
|
for (let i = 0; i < m.options.samples; i++) {
|
|
98
122
|
const iterations = baseIterations * (1 + (i % m.options.sweepWidth));
|
|
99
123
|
const duration = measure(m, iterations);
|
|
100
124
|
samples.push({ duration, iterations });
|
|
125
|
+
if (i % tickEvery === 0) {
|
|
126
|
+
onTick();
|
|
127
|
+
}
|
|
101
128
|
}
|
|
102
|
-
const { beta,
|
|
129
|
+
const { beta, confidence, outliers } = regress(m, samples);
|
|
103
130
|
const ops = 1 / beta;
|
|
104
|
-
const lowOps = 1 / (beta +
|
|
105
|
-
const highOps = 1 / (beta -
|
|
131
|
+
const lowOps = 1 / (beta + confidence);
|
|
132
|
+
const highOps = 1 / (beta - confidence);
|
|
106
133
|
const maxError = Math.max(highOps - ops, ops - lowOps);
|
|
107
134
|
const usedSamples = samples.length - outliers;
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
return {
|
|
136
|
+
ops,
|
|
137
|
+
maxError,
|
|
138
|
+
usedSamples,
|
|
139
|
+
};
|
|
110
140
|
}
|
|
111
141
|
function warmUp(m) {
|
|
112
142
|
// Initial warm-up
|
|
@@ -195,15 +225,23 @@ function regress(m, samples) {
|
|
|
195
225
|
stdError /= withoutOutliers.length - 2;
|
|
196
226
|
stdError /= betaDenom;
|
|
197
227
|
stdError = Math.sqrt(stdError);
|
|
198
|
-
// t-distribution value for large sample count and p=0.05
|
|
199
|
-
const T_VALUE = 1.9719;
|
|
200
228
|
return {
|
|
201
229
|
alpha,
|
|
202
230
|
beta,
|
|
203
|
-
|
|
231
|
+
confidence: STUDENT_T * stdError,
|
|
204
232
|
outliers: samples.length - withoutOutliers.length,
|
|
205
233
|
};
|
|
206
234
|
}
|
|
235
|
+
function style(text, code) {
|
|
236
|
+
return `\x1b[${code}m${text}\x1b[m`;
|
|
237
|
+
}
|
|
238
|
+
function nice(n) {
|
|
239
|
+
let result = n.toFixed(1);
|
|
240
|
+
for (let i = result.length - 5; i > 0; i -= 3) {
|
|
241
|
+
result = result.slice(0, i) + "'" + result.slice(i);
|
|
242
|
+
}
|
|
243
|
+
return result;
|
|
244
|
+
}
|
|
207
245
|
main().catch((err) => {
|
|
208
246
|
console.error(err);
|
|
209
247
|
process.exit(1);
|