@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.
Files changed (2) hide show
  1. package/dist/bin/bencher.js +37 -11
  2. package/package.json +1 -1
@@ -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
- process.stdout.write(`${style(paddedName, BOLD)}: running...\n`);
103
- const { ops, maxError, usedSamples } = run(m);
104
- process.stdout.write(PREV_LINE);
105
- process.stdout.write(`${style(paddedName, BOLD)}: ${ops.toFixed(1)} ops/s ` +
106
- style(`(±${maxError.toFixed(1)}, p=${P_VALUE}, n=${usedSamples})`, ITALIC) +
107
- '\n');
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
- iterations = Math.max(iterations / 2, (maxSampleDuration / duration) * iterations);
149
- return iterations;
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indutny/bencher",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Simple benchmarking tool",
5
5
  "bin": {
6
6
  "bencher": "./dist/bin/bencher.js"