@indutny/bencher 1.1.2 → 1.1.4
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 +37 -11
- package/package.json +1 -1
package/dist/bin/bencher.js
CHANGED
|
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
28
|
};
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const fs_1 = require("fs");
|
|
30
31
|
const promises_1 = require("fs/promises");
|
|
31
32
|
const yargs_1 = __importDefault(require("yargs"));
|
|
32
33
|
const helpers_1 = require("yargs/helpers");
|
|
@@ -35,6 +36,8 @@ const BOLD = 1;
|
|
|
35
36
|
const ITALIC = 3;
|
|
36
37
|
// Go back to previous line, clear the line
|
|
37
38
|
const PREV_LINE = '\x1b[F\x1b[K';
|
|
39
|
+
const SPINNER = ['⠋', '⠙', '⠸', '⠴', '⠦', '⠇'];
|
|
40
|
+
const TICK_FREQUENCY = 1 / 4;
|
|
38
41
|
// t-distribution value for large sample count and p=0.001
|
|
39
42
|
// https://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
|
|
40
43
|
const STUDENT_T = 3.09;
|
|
@@ -98,22 +101,37 @@ async function main() {
|
|
|
98
101
|
}));
|
|
99
102
|
const maxNameLength = modules.reduce((len, { name }) => Math.max(len, name.length), 0);
|
|
100
103
|
for (const m of modules) {
|
|
101
|
-
const paddedName = m.name + ' '.repeat(maxNameLength - m.name.length);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
const paddedName = style(m.name, BOLD) + ':' + ' '.repeat(maxNameLength - m.name.length);
|
|
105
|
+
// Just to reserve the line
|
|
106
|
+
(0, fs_1.writeSync)(process.stdout.fd, '\n');
|
|
107
|
+
let ticks = 0;
|
|
108
|
+
const onTick = () => {
|
|
109
|
+
(0, fs_1.writeSync)(process.stdout.fd, `${PREV_LINE}${paddedName} ${SPINNER[ticks]}\n`);
|
|
110
|
+
ticks = (ticks + 1) % SPINNER.length;
|
|
111
|
+
};
|
|
112
|
+
onTick();
|
|
113
|
+
const { ops, maxError, usedSamples } = run(m, {
|
|
114
|
+
onTick,
|
|
115
|
+
});
|
|
116
|
+
const stats = style(`(±${nice(maxError)}, p=${P_VALUE}, n=${usedSamples})`, ITALIC);
|
|
117
|
+
(0, fs_1.writeSync)(process.stdout.fd, `${PREV_LINE}${paddedName} ${nice(ops)} ops/sec ${stats}\n`);
|
|
108
118
|
}
|
|
109
119
|
}
|
|
110
|
-
function run(m) {
|
|
111
|
-
const baseIterations = warmUp(m);
|
|
120
|
+
function run(m, { onTick }) {
|
|
121
|
+
const { baseIterations, iterationTime } = warmUp(m);
|
|
112
122
|
const samples = new Array();
|
|
123
|
+
const tickEvery = TICK_FREQUENCY / iterationTime;
|
|
124
|
+
let totalIterations = 0;
|
|
125
|
+
let nextTick = tickEvery;
|
|
113
126
|
for (let i = 0; i < m.options.samples; i++) {
|
|
114
127
|
const iterations = baseIterations * (1 + (i % m.options.sweepWidth));
|
|
115
128
|
const duration = measure(m, iterations);
|
|
116
129
|
samples.push({ duration, iterations });
|
|
130
|
+
totalIterations += iterations;
|
|
131
|
+
while (totalIterations > nextTick) {
|
|
132
|
+
onTick();
|
|
133
|
+
nextTick += tickEvery;
|
|
134
|
+
}
|
|
117
135
|
}
|
|
118
136
|
const { beta, confidence, outliers } = regress(m, samples);
|
|
119
137
|
const ops = 1 / beta;
|
|
@@ -145,8 +163,9 @@ function warmUp(m) {
|
|
|
145
163
|
iterations *= 2;
|
|
146
164
|
duration = measure(m, Math.round(iterations));
|
|
147
165
|
} while (duration < maxSampleDuration);
|
|
148
|
-
|
|
149
|
-
|
|
166
|
+
const iterationTime = duration / Math.round(iterations);
|
|
167
|
+
iterations = Math.round(Math.max(iterations / 2, (maxSampleDuration / duration) * iterations));
|
|
168
|
+
return { baseIterations: iterations, iterationTime };
|
|
150
169
|
}
|
|
151
170
|
function measure(m, iterations) {
|
|
152
171
|
let sum = 0;
|
|
@@ -224,6 +243,13 @@ function regress(m, samples) {
|
|
|
224
243
|
function style(text, code) {
|
|
225
244
|
return `\x1b[${code}m${text}\x1b[m`;
|
|
226
245
|
}
|
|
246
|
+
function nice(n) {
|
|
247
|
+
let result = n.toFixed(1);
|
|
248
|
+
for (let i = result.length - 5; i > 0; i -= 3) {
|
|
249
|
+
result = result.slice(0, i) + "'" + result.slice(i);
|
|
250
|
+
}
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
227
253
|
main().catch((err) => {
|
|
228
254
|
console.error(err);
|
|
229
255
|
process.exit(1);
|