overtake 1.4.0 → 2.0.0

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 (57) hide show
  1. package/README.md +4 -15
  2. package/bin/overtake.js +1 -1
  3. package/build/executor.d.ts +7 -3
  4. package/build/index.d.ts +10 -11
  5. package/build/reporter.d.ts +10 -2
  6. package/build/runner.d.ts +1 -1
  7. package/build/types.d.ts +6 -6
  8. package/build/utils.d.ts +1 -17
  9. package/package.json +8 -26
  10. package/src/__tests__/assert-no-closure.ts +135 -0
  11. package/src/__tests__/benchmark-execute.ts +48 -0
  12. package/src/cli.ts +139 -144
  13. package/src/executor.ts +48 -18
  14. package/src/index.ts +85 -57
  15. package/src/reporter.ts +27 -19
  16. package/src/runner.ts +2 -5
  17. package/src/types.ts +8 -8
  18. package/src/utils.ts +15 -54
  19. package/src/worker.ts +6 -3
  20. package/tsconfig.json +3 -1
  21. package/build/cli.cjs +0 -179
  22. package/build/cli.cjs.map +0 -1
  23. package/build/cli.js +0 -134
  24. package/build/cli.js.map +0 -1
  25. package/build/executor.cjs +0 -123
  26. package/build/executor.cjs.map +0 -1
  27. package/build/executor.js +0 -113
  28. package/build/executor.js.map +0 -1
  29. package/build/gc-watcher.cjs +0 -30
  30. package/build/gc-watcher.cjs.map +0 -1
  31. package/build/gc-watcher.js +0 -20
  32. package/build/gc-watcher.js.map +0 -1
  33. package/build/index.cjs +0 -442
  34. package/build/index.cjs.map +0 -1
  35. package/build/index.js +0 -377
  36. package/build/index.js.map +0 -1
  37. package/build/reporter.cjs +0 -311
  38. package/build/reporter.cjs.map +0 -1
  39. package/build/reporter.js +0 -293
  40. package/build/reporter.js.map +0 -1
  41. package/build/runner.cjs +0 -532
  42. package/build/runner.cjs.map +0 -1
  43. package/build/runner.js +0 -522
  44. package/build/runner.js.map +0 -1
  45. package/build/types.cjs +0 -66
  46. package/build/types.cjs.map +0 -1
  47. package/build/types.js +0 -33
  48. package/build/types.js.map +0 -1
  49. package/build/utils.cjs +0 -174
  50. package/build/utils.cjs.map +0 -1
  51. package/build/utils.js +0 -132
  52. package/build/utils.js.map +0 -1
  53. package/build/worker.cjs +0 -155
  54. package/build/worker.cjs.map +0 -1
  55. package/build/worker.js +0 -110
  56. package/build/worker.js.map +0 -1
  57. package/src/__tests__/assert-no-closure.js +0 -134
@@ -1,311 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get Report () {
13
- return Report;
14
- },
15
- get createReport () {
16
- return createReport;
17
- }
18
- });
19
- const _utilscjs = require("./utils.cjs");
20
- const _typescjs = require("./types.cjs");
21
- const units = [
22
- {
23
- unit: 'ns',
24
- factor: 1
25
- },
26
- {
27
- unit: 'µs',
28
- factor: 1e3
29
- },
30
- {
31
- unit: 'ms',
32
- factor: 1e6
33
- },
34
- {
35
- unit: 's',
36
- factor: 1e9
37
- },
38
- {
39
- unit: 'm',
40
- factor: 60 * 1e9
41
- },
42
- {
43
- unit: 'h',
44
- factor: 3600 * 1e9
45
- }
46
- ];
47
- function smartFixed(n) {
48
- return n.toLocaleString(undefined, {
49
- minimumFractionDigits: 0,
50
- maximumFractionDigits: 2,
51
- useGrouping: true
52
- });
53
- }
54
- class Report {
55
- type;
56
- value;
57
- uncertainty;
58
- scale;
59
- constructor(type, value, uncertainty = 0, scale = 1n){
60
- this.type = type;
61
- this.value = value;
62
- this.uncertainty = uncertainty;
63
- this.scale = scale;
64
- }
65
- valueOf() {
66
- return Number((0, _utilscjs.div)(this.value, this.scale));
67
- }
68
- toString() {
69
- const uncertainty = this.uncertainty ? ` ± ${smartFixed(this.uncertainty)}%` : '';
70
- const value = this.valueOf();
71
- if (this.type === 'ops') {
72
- return `${smartFixed(value)} ops/s${uncertainty}`;
73
- }
74
- if (this.type === 'rme') {
75
- return `${smartFixed(value)}%`;
76
- }
77
- if (this.type === 'variance') {
78
- let display = value;
79
- let unit = 'ns²';
80
- const varianceUnits = [
81
- {
82
- unit: 'ns²',
83
- factor: 1
84
- },
85
- {
86
- unit: 'µs²',
87
- factor: 1e6
88
- },
89
- {
90
- unit: 'ms²',
91
- factor: 1e12
92
- }
93
- ];
94
- for (const { unit: u, factor } of varianceUnits){
95
- const candidate = value / factor;
96
- if (candidate < 1000) {
97
- display = candidate;
98
- unit = u;
99
- break;
100
- }
101
- }
102
- return `${smartFixed(display)} ${unit}`;
103
- }
104
- let display = value;
105
- let unit = 'ns';
106
- for (const { unit: u, factor } of units){
107
- const candidate = value / factor;
108
- if (candidate < 1000) {
109
- display = candidate;
110
- unit = u;
111
- break;
112
- }
113
- }
114
- return `${smartFixed(display)} ${unit}${uncertainty}`;
115
- }
116
- }
117
- const SQRT_SCALE = 1_000_000n;
118
- const SQRT_SCALE_SQ = SQRT_SCALE * SQRT_SCALE;
119
- const Z95_NUM = 196n;
120
- const Z95_DENOM = 100n;
121
- const computeStats = (durations)=>{
122
- let sum = 0n;
123
- for (const d of durations)sum += d;
124
- const n = BigInt(durations.length);
125
- const mean = sum / n;
126
- let ssd = 0n;
127
- for (const d of durations){
128
- const diff = d - mean;
129
- ssd += diff * diff;
130
- }
131
- return {
132
- sum,
133
- mean,
134
- ssd,
135
- n
136
- };
137
- };
138
- const createReport = (durations, type)=>{
139
- const n = durations.length;
140
- if (n === 0) {
141
- return new Report(type, 0n);
142
- }
143
- switch(type){
144
- case 'min':
145
- {
146
- return new Report(type, durations[0], 0, _typescjs.DURATION_SCALE);
147
- }
148
- case 'max':
149
- {
150
- return new Report(type, durations[n - 1], 0, _typescjs.DURATION_SCALE);
151
- }
152
- case 'median':
153
- {
154
- const mid = Math.floor(n / 2);
155
- const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];
156
- return new Report(type, med, 0, _typescjs.DURATION_SCALE);
157
- }
158
- case 'mode':
159
- {
160
- const freq = new Map();
161
- let maxCount = 0n;
162
- let modeVal = durations[0];
163
- for (const d of durations){
164
- const count = (freq.get(d) || 0n) + 1n;
165
- freq.set(d, count);
166
- if (count > maxCount) {
167
- maxCount = count;
168
- modeVal = d;
169
- }
170
- }
171
- let lower = modeVal;
172
- let upper = modeVal;
173
- const firstIdx = durations.indexOf(modeVal);
174
- const lastIdx = durations.lastIndexOf(modeVal);
175
- if (firstIdx > 0) lower = durations[firstIdx - 1];
176
- if (lastIdx < n - 1) upper = durations[lastIdx + 1];
177
- const gap = (0, _utilscjs.max)(modeVal - lower, upper - modeVal);
178
- const uncertainty = modeVal > 0 ? Number(gap / 2n * 100n / modeVal) : 0;
179
- return new Report(type, modeVal, uncertainty, _typescjs.DURATION_SCALE);
180
- }
181
- case 'ops':
182
- {
183
- const { mean: avgScaled, ssd, n: nBig } = computeStats(durations);
184
- const nsPerSecScaled = 1_000_000_000n * _typescjs.DURATION_SCALE;
185
- const raw = Number(nsPerSecScaled) / Number(avgScaled);
186
- const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
187
- const exp = raw > 100 ? 0 : 2 + extra;
188
- const scale = 10n ** BigInt(exp);
189
- const value = avgScaled > 0n ? nsPerSecScaled * scale / avgScaled : 0n;
190
- let uncertainty = 0;
191
- if (n >= 2 && avgScaled > 0n) {
192
- const RME_PRECISION = 1_000_000n;
193
- const semOverMeanSqScaled = ssd * RME_PRECISION * RME_PRECISION / (BigInt(n - 1) * nBig * avgScaled * avgScaled);
194
- const semOverMeanScaled = (0, _utilscjs.isqrt)(semOverMeanSqScaled);
195
- uncertainty = Number(Z95_NUM * semOverMeanScaled) / Number(RME_PRECISION);
196
- }
197
- return new Report(type, value, uncertainty, scale);
198
- }
199
- case 'mean':
200
- {
201
- const { sum } = computeStats(durations);
202
- const value = (0, _utilscjs.divs)(sum, BigInt(n), 1n);
203
- return new Report(type, value, 0, _typescjs.DURATION_SCALE);
204
- }
205
- case 'variance':
206
- {
207
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE * _typescjs.DURATION_SCALE);
208
- const { ssd } = computeStats(durations);
209
- const variance = ssd / BigInt(n - 1);
210
- return new Report(type, variance, 0, _typescjs.DURATION_SCALE * _typescjs.DURATION_SCALE);
211
- }
212
- case 'sd':
213
- {
214
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
215
- const { ssd } = computeStats(durations);
216
- const scaledVariance = ssd * SQRT_SCALE_SQ / BigInt(n - 1);
217
- const sdScaled = (0, _utilscjs.isqrt)(scaledVariance);
218
- return new Report(type, sdScaled, 0, _typescjs.DURATION_SCALE * SQRT_SCALE);
219
- }
220
- case 'sem':
221
- {
222
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
223
- const { ssd, n: nBig } = computeStats(durations);
224
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
225
- const semScaled = (0, _utilscjs.isqrt)(semSqScaled);
226
- return new Report(type, semScaled, 0, _typescjs.DURATION_SCALE * SQRT_SCALE);
227
- }
228
- case 'moe':
229
- {
230
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
231
- const { ssd, n: nBig } = computeStats(durations);
232
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
233
- const semScaled = (0, _utilscjs.isqrt)(semSqScaled);
234
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
235
- return new Report(type, moeScaled, 0, _typescjs.DURATION_SCALE * SQRT_SCALE);
236
- }
237
- case 'rme':
238
- {
239
- if (n < 2) return new Report(type, 0n);
240
- const { mean, ssd, n: nBig } = computeStats(durations);
241
- if (mean === 0n) return new Report(type, 0n);
242
- const RME_PRECISION = 1_000_000n;
243
- const semOverMeanSqScaled = ssd * RME_PRECISION * RME_PRECISION / (BigInt(n - 1) * nBig * mean * mean);
244
- const semOverMeanScaled = (0, _utilscjs.isqrt)(semOverMeanSqScaled);
245
- const rmeScaled = Z95_NUM * semOverMeanScaled * 100n / RME_PRECISION;
246
- return new Report(type, rmeScaled, 0, 100n);
247
- }
248
- case 'mad':
249
- {
250
- const medianIdx = Math.floor(n / 2);
251
- const median = n % 2 === 1 ? durations[medianIdx] : (durations[medianIdx - 1] + durations[medianIdx]) / 2n;
252
- const deviations = new BigUint64Array(n);
253
- for(let i = 0; i < n; i++){
254
- const diff = durations[i] > median ? durations[i] - median : median - durations[i];
255
- deviations[i] = diff;
256
- }
257
- deviations.sort();
258
- const madIdx = Math.floor(n / 2);
259
- const mad = n % 2 === 1 ? deviations[madIdx] : (deviations[madIdx - 1] + deviations[madIdx]) / 2n;
260
- return new Report(type, mad, 0, _typescjs.DURATION_SCALE);
261
- }
262
- case 'iqr':
263
- {
264
- const q1Idx = Math.floor(n * 0.25);
265
- const q3Idx = Math.floor(n * 0.75);
266
- const q1 = durations[q1Idx];
267
- const q3 = durations[q3Idx];
268
- const iqr = q3 - q1;
269
- return new Report(type, iqr, 0, _typescjs.DURATION_SCALE);
270
- }
271
- case 'ci_lower':
272
- {
273
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
274
- const { mean, ssd, n: nBig } = computeStats(durations);
275
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
276
- const semScaled = (0, _utilscjs.isqrt)(semSqScaled);
277
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
278
- const ciLowerScaled = mean * SQRT_SCALE - moeScaled;
279
- return new Report(type, ciLowerScaled > 0n ? ciLowerScaled : 0n, 0, _typescjs.DURATION_SCALE * SQRT_SCALE);
280
- }
281
- case 'ci_upper':
282
- {
283
- if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
284
- const { mean, ssd, n: nBig } = computeStats(durations);
285
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
286
- const semScaled = (0, _utilscjs.isqrt)(semSqScaled);
287
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
288
- const ciUpperScaled = mean * SQRT_SCALE + moeScaled;
289
- return new Report(type, ciUpperScaled, 0, _typescjs.DURATION_SCALE * SQRT_SCALE);
290
- }
291
- default:
292
- {
293
- const p = Number(type.slice(1));
294
- if (p === 0) {
295
- return new Report(type, durations[0], 0, _typescjs.DURATION_SCALE);
296
- }
297
- if (p === 100) {
298
- return new Report(type, durations[n - 1], 0, _typescjs.DURATION_SCALE);
299
- }
300
- const idx = Math.ceil(p / 100 * n) - 1;
301
- const value = durations[Math.min(Math.max(idx, 0), n - 1)];
302
- const prev = idx > 0 ? durations[idx - 1] : value;
303
- const next = idx < n - 1 ? durations[idx + 1] : value;
304
- const gap = (0, _utilscjs.max)(value - prev, next - value);
305
- const uncertainty = value > 0 ? Number((0, _utilscjs.div)((0, _utilscjs.divs)(gap, 2n, 100_00n), value)) / 100 : 0;
306
- return new Report(type, value, uncertainty, _typescjs.DURATION_SCALE);
307
- }
308
- }
309
- };
310
-
311
- //# sourceMappingURL=reporter.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["import { div, max, divs, isqrt } from './utils.js';\nimport { ReportType, DURATION_SCALE } from './types.js';\n\nconst units = [\n { unit: 'ns', factor: 1 },\n { unit: 'µs', factor: 1e3 },\n { unit: 'ms', factor: 1e6 },\n { unit: 's', factor: 1e9 },\n { unit: 'm', factor: 60 * 1e9 },\n { unit: 'h', factor: 3600 * 1e9 },\n] as const;\n\nfunction smartFixed(n: number): string {\n return n.toLocaleString(undefined, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n useGrouping: true,\n });\n}\nexport class Report {\n constructor(\n public readonly type: ReportType,\n public readonly value: bigint,\n public readonly uncertainty: number = 0,\n public readonly scale: bigint = 1n,\n ) {}\n valueOf() {\n return Number(div(this.value, this.scale));\n }\n toString() {\n const uncertainty = this.uncertainty ? ` ± ${smartFixed(this.uncertainty)}%` : '';\n\n const value = this.valueOf();\n if (this.type === 'ops') {\n return `${smartFixed(value)} ops/s${uncertainty}`;\n }\n if (this.type === 'rme') {\n return `${smartFixed(value)}%`;\n }\n if (this.type === 'variance') {\n let display = value;\n let unit = 'ns²';\n const varianceUnits = [\n { unit: 'ns²', factor: 1 },\n { unit: 'µs²', factor: 1e6 },\n { unit: 'ms²', factor: 1e12 },\n ];\n for (const { unit: u, factor } of varianceUnits) {\n const candidate = value / factor;\n if (candidate < 1000) {\n display = candidate;\n unit = u;\n break;\n }\n }\n return `${smartFixed(display)} ${unit}`;\n }\n let display = value;\n let unit = 'ns';\n\n for (const { unit: u, factor } of units) {\n const candidate = value / factor;\n if (candidate < 1000) {\n display = candidate;\n unit = u;\n break;\n }\n }\n return `${smartFixed(display)} ${unit}${uncertainty}`;\n }\n}\n\nconst SQRT_SCALE = 1_000_000n;\nconst SQRT_SCALE_SQ = SQRT_SCALE * SQRT_SCALE;\nconst Z95_NUM = 196n;\nconst Z95_DENOM = 100n;\n\nconst computeStats = (durations: BigUint64Array) => {\n let sum = 0n;\n for (const d of durations) sum += d;\n const n = BigInt(durations.length);\n const mean = sum / n;\n let ssd = 0n;\n for (const d of durations) {\n const diff = d - mean;\n ssd += diff * diff;\n }\n return { sum, mean, ssd, n };\n};\n\nexport const createReport = (durations: BigUint64Array, type: ReportType): Report => {\n const n = durations.length;\n if (n === 0) {\n return new Report(type, 0n);\n }\n switch (type) {\n case 'min': {\n return new Report(type, durations[0], 0, DURATION_SCALE);\n }\n case 'max': {\n return new Report(type, durations[n - 1], 0, DURATION_SCALE);\n }\n case 'median': {\n const mid = Math.floor(n / 2);\n const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];\n return new Report(type, med, 0, DURATION_SCALE);\n }\n\n case 'mode': {\n const freq = new Map<bigint, bigint>();\n let maxCount = 0n;\n let modeVal = durations[0];\n for (const d of durations) {\n const count = (freq.get(d) || 0n) + 1n;\n freq.set(d, count);\n if (count > maxCount) {\n maxCount = count;\n modeVal = d;\n }\n }\n let lower = modeVal;\n let upper = modeVal;\n const firstIdx = durations.indexOf(modeVal);\n const lastIdx = durations.lastIndexOf(modeVal);\n if (firstIdx > 0) lower = durations[firstIdx - 1];\n if (lastIdx < n - 1) upper = durations[lastIdx + 1];\n const gap = max(modeVal - lower, upper - modeVal);\n const uncertainty = modeVal > 0 ? Number(((gap / 2n) * 100n) / modeVal) : 0;\n return new Report(type, modeVal, uncertainty, DURATION_SCALE);\n }\n\n case 'ops': {\n const { mean: avgScaled, ssd, n: nBig } = computeStats(durations);\n const nsPerSecScaled = 1_000_000_000n * DURATION_SCALE;\n const raw = Number(nsPerSecScaled) / Number(avgScaled);\n const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;\n\n const exp = raw > 100 ? 0 : 2 + extra;\n\n const scale = 10n ** BigInt(exp);\n\n const value = avgScaled > 0n ? (nsPerSecScaled * scale) / avgScaled : 0n;\n let uncertainty = 0;\n if (n >= 2 && avgScaled > 0n) {\n const RME_PRECISION = 1_000_000n;\n const semOverMeanSqScaled = (ssd * RME_PRECISION * RME_PRECISION) / (BigInt(n - 1) * nBig * avgScaled * avgScaled);\n const semOverMeanScaled = isqrt(semOverMeanSqScaled);\n uncertainty = Number(Z95_NUM * semOverMeanScaled) / Number(RME_PRECISION);\n }\n return new Report(type, value, uncertainty, scale);\n }\n case 'mean': {\n const { sum } = computeStats(durations);\n const value = divs(sum, BigInt(n), 1n);\n return new Report(type, value, 0, DURATION_SCALE);\n }\n\n case 'variance': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE * DURATION_SCALE);\n const { ssd } = computeStats(durations);\n const variance = ssd / BigInt(n - 1);\n return new Report(type, variance, 0, DURATION_SCALE * DURATION_SCALE);\n }\n\n case 'sd': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n const { ssd } = computeStats(durations);\n const scaledVariance = (ssd * SQRT_SCALE_SQ) / BigInt(n - 1);\n const sdScaled = isqrt(scaledVariance);\n return new Report(type, sdScaled, 0, DURATION_SCALE * SQRT_SCALE);\n }\n\n case 'sem': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n const { ssd, n: nBig } = computeStats(durations);\n const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);\n const semScaled = isqrt(semSqScaled);\n return new Report(type, semScaled, 0, DURATION_SCALE * SQRT_SCALE);\n }\n\n case 'moe': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n const { ssd, n: nBig } = computeStats(durations);\n const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);\n const semScaled = isqrt(semSqScaled);\n const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;\n return new Report(type, moeScaled, 0, DURATION_SCALE * SQRT_SCALE);\n }\n\n case 'rme': {\n if (n < 2) return new Report(type, 0n);\n const { mean, ssd, n: nBig } = computeStats(durations);\n if (mean === 0n) return new Report(type, 0n);\n const RME_PRECISION = 1_000_000n;\n const semOverMeanSqScaled = (ssd * RME_PRECISION * RME_PRECISION) / (BigInt(n - 1) * nBig * mean * mean);\n const semOverMeanScaled = isqrt(semOverMeanSqScaled);\n const rmeScaled = (Z95_NUM * semOverMeanScaled * 100n) / RME_PRECISION;\n return new Report(type, rmeScaled, 0, 100n);\n }\n\n case 'mad': {\n const medianIdx = Math.floor(n / 2);\n const median = n % 2 === 1 ? durations[medianIdx] : (durations[medianIdx - 1] + durations[medianIdx]) / 2n;\n const deviations = new BigUint64Array(n);\n for (let i = 0; i < n; i++) {\n const diff = durations[i] > median ? durations[i] - median : median - durations[i];\n deviations[i] = diff;\n }\n deviations.sort();\n const madIdx = Math.floor(n / 2);\n const mad = n % 2 === 1 ? deviations[madIdx] : (deviations[madIdx - 1] + deviations[madIdx]) / 2n;\n return new Report(type, mad, 0, DURATION_SCALE);\n }\n\n case 'iqr': {\n const q1Idx = Math.floor(n * 0.25);\n const q3Idx = Math.floor(n * 0.75);\n const q1 = durations[q1Idx];\n const q3 = durations[q3Idx];\n const iqr = q3 - q1;\n return new Report(type, iqr, 0, DURATION_SCALE);\n }\n\n case 'ci_lower': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n const { mean, ssd, n: nBig } = computeStats(durations);\n const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);\n const semScaled = isqrt(semSqScaled);\n const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;\n const ciLowerScaled = mean * SQRT_SCALE - moeScaled;\n return new Report(type, ciLowerScaled > 0n ? ciLowerScaled : 0n, 0, DURATION_SCALE * SQRT_SCALE);\n }\n\n case 'ci_upper': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n const { mean, ssd, n: nBig } = computeStats(durations);\n const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);\n const semScaled = isqrt(semSqScaled);\n const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;\n const ciUpperScaled = mean * SQRT_SCALE + moeScaled;\n return new Report(type, ciUpperScaled, 0, DURATION_SCALE * SQRT_SCALE);\n }\n\n default: {\n const p = Number(type.slice(1));\n if (p === 0) {\n return new Report(type, durations[0], 0, DURATION_SCALE);\n }\n if (p === 100) {\n return new Report(type, durations[n - 1], 0, DURATION_SCALE);\n }\n const idx = Math.ceil((p / 100) * n) - 1;\n const value = durations[Math.min(Math.max(idx, 0), n - 1)];\n const prev = idx > 0 ? durations[idx - 1] : value;\n const next = idx < n - 1 ? durations[idx + 1] : value;\n const gap = max(value - prev, next - value);\n const uncertainty = value > 0 ? Number(div(divs(gap, 2n, 100_00n), value)) / 100 : 0;\n\n return new Report(type, value, uncertainty, DURATION_SCALE);\n }\n }\n};\n"],"names":["Report","createReport","units","unit","factor","smartFixed","n","toLocaleString","undefined","minimumFractionDigits","maximumFractionDigits","useGrouping","type","value","uncertainty","scale","valueOf","Number","div","toString","display","varianceUnits","u","candidate","SQRT_SCALE","SQRT_SCALE_SQ","Z95_NUM","Z95_DENOM","computeStats","durations","sum","d","BigInt","length","mean","ssd","diff","DURATION_SCALE","mid","Math","floor","med","freq","Map","maxCount","modeVal","count","get","set","lower","upper","firstIdx","indexOf","lastIdx","lastIndexOf","gap","max","avgScaled","nBig","nsPerSecScaled","raw","extra","ceil","log10","exp","RME_PRECISION","semOverMeanSqScaled","semOverMeanScaled","isqrt","divs","variance","scaledVariance","sdScaled","semSqScaled","semScaled","moeScaled","rmeScaled","medianIdx","median","deviations","BigUint64Array","i","sort","madIdx","mad","q1Idx","q3Idx","q1","q3","iqr","ciLowerScaled","ciUpperScaled","p","slice","idx","min","prev","next"],"mappings":"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"}
package/build/reporter.js DELETED
@@ -1,293 +0,0 @@
1
- import { div, max, divs, isqrt } from "./utils.js";
2
- import { DURATION_SCALE } from "./types.js";
3
- const units = [
4
- {
5
- unit: 'ns',
6
- factor: 1
7
- },
8
- {
9
- unit: 'µs',
10
- factor: 1e3
11
- },
12
- {
13
- unit: 'ms',
14
- factor: 1e6
15
- },
16
- {
17
- unit: 's',
18
- factor: 1e9
19
- },
20
- {
21
- unit: 'm',
22
- factor: 60 * 1e9
23
- },
24
- {
25
- unit: 'h',
26
- factor: 3600 * 1e9
27
- }
28
- ];
29
- function smartFixed(n) {
30
- return n.toLocaleString(undefined, {
31
- minimumFractionDigits: 0,
32
- maximumFractionDigits: 2,
33
- useGrouping: true
34
- });
35
- }
36
- export class Report {
37
- type;
38
- value;
39
- uncertainty;
40
- scale;
41
- constructor(type, value, uncertainty = 0, scale = 1n){
42
- this.type = type;
43
- this.value = value;
44
- this.uncertainty = uncertainty;
45
- this.scale = scale;
46
- }
47
- valueOf() {
48
- return Number(div(this.value, this.scale));
49
- }
50
- toString() {
51
- const uncertainty = this.uncertainty ? ` ± ${smartFixed(this.uncertainty)}%` : '';
52
- const value = this.valueOf();
53
- if (this.type === 'ops') {
54
- return `${smartFixed(value)} ops/s${uncertainty}`;
55
- }
56
- if (this.type === 'rme') {
57
- return `${smartFixed(value)}%`;
58
- }
59
- if (this.type === 'variance') {
60
- let display = value;
61
- let unit = 'ns²';
62
- const varianceUnits = [
63
- {
64
- unit: 'ns²',
65
- factor: 1
66
- },
67
- {
68
- unit: 'µs²',
69
- factor: 1e6
70
- },
71
- {
72
- unit: 'ms²',
73
- factor: 1e12
74
- }
75
- ];
76
- for (const { unit: u, factor } of varianceUnits){
77
- const candidate = value / factor;
78
- if (candidate < 1000) {
79
- display = candidate;
80
- unit = u;
81
- break;
82
- }
83
- }
84
- return `${smartFixed(display)} ${unit}`;
85
- }
86
- let display = value;
87
- let unit = 'ns';
88
- for (const { unit: u, factor } of units){
89
- const candidate = value / factor;
90
- if (candidate < 1000) {
91
- display = candidate;
92
- unit = u;
93
- break;
94
- }
95
- }
96
- return `${smartFixed(display)} ${unit}${uncertainty}`;
97
- }
98
- }
99
- const SQRT_SCALE = 1_000_000n;
100
- const SQRT_SCALE_SQ = SQRT_SCALE * SQRT_SCALE;
101
- const Z95_NUM = 196n;
102
- const Z95_DENOM = 100n;
103
- const computeStats = (durations)=>{
104
- let sum = 0n;
105
- for (const d of durations)sum += d;
106
- const n = BigInt(durations.length);
107
- const mean = sum / n;
108
- let ssd = 0n;
109
- for (const d of durations){
110
- const diff = d - mean;
111
- ssd += diff * diff;
112
- }
113
- return {
114
- sum,
115
- mean,
116
- ssd,
117
- n
118
- };
119
- };
120
- export const createReport = (durations, type)=>{
121
- const n = durations.length;
122
- if (n === 0) {
123
- return new Report(type, 0n);
124
- }
125
- switch(type){
126
- case 'min':
127
- {
128
- return new Report(type, durations[0], 0, DURATION_SCALE);
129
- }
130
- case 'max':
131
- {
132
- return new Report(type, durations[n - 1], 0, DURATION_SCALE);
133
- }
134
- case 'median':
135
- {
136
- const mid = Math.floor(n / 2);
137
- const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];
138
- return new Report(type, med, 0, DURATION_SCALE);
139
- }
140
- case 'mode':
141
- {
142
- const freq = new Map();
143
- let maxCount = 0n;
144
- let modeVal = durations[0];
145
- for (const d of durations){
146
- const count = (freq.get(d) || 0n) + 1n;
147
- freq.set(d, count);
148
- if (count > maxCount) {
149
- maxCount = count;
150
- modeVal = d;
151
- }
152
- }
153
- let lower = modeVal;
154
- let upper = modeVal;
155
- const firstIdx = durations.indexOf(modeVal);
156
- const lastIdx = durations.lastIndexOf(modeVal);
157
- if (firstIdx > 0) lower = durations[firstIdx - 1];
158
- if (lastIdx < n - 1) upper = durations[lastIdx + 1];
159
- const gap = max(modeVal - lower, upper - modeVal);
160
- const uncertainty = modeVal > 0 ? Number(gap / 2n * 100n / modeVal) : 0;
161
- return new Report(type, modeVal, uncertainty, DURATION_SCALE);
162
- }
163
- case 'ops':
164
- {
165
- const { mean: avgScaled, ssd, n: nBig } = computeStats(durations);
166
- const nsPerSecScaled = 1_000_000_000n * DURATION_SCALE;
167
- const raw = Number(nsPerSecScaled) / Number(avgScaled);
168
- const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
169
- const exp = raw > 100 ? 0 : 2 + extra;
170
- const scale = 10n ** BigInt(exp);
171
- const value = avgScaled > 0n ? nsPerSecScaled * scale / avgScaled : 0n;
172
- let uncertainty = 0;
173
- if (n >= 2 && avgScaled > 0n) {
174
- const RME_PRECISION = 1_000_000n;
175
- const semOverMeanSqScaled = ssd * RME_PRECISION * RME_PRECISION / (BigInt(n - 1) * nBig * avgScaled * avgScaled);
176
- const semOverMeanScaled = isqrt(semOverMeanSqScaled);
177
- uncertainty = Number(Z95_NUM * semOverMeanScaled) / Number(RME_PRECISION);
178
- }
179
- return new Report(type, value, uncertainty, scale);
180
- }
181
- case 'mean':
182
- {
183
- const { sum } = computeStats(durations);
184
- const value = divs(sum, BigInt(n), 1n);
185
- return new Report(type, value, 0, DURATION_SCALE);
186
- }
187
- case 'variance':
188
- {
189
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE * DURATION_SCALE);
190
- const { ssd } = computeStats(durations);
191
- const variance = ssd / BigInt(n - 1);
192
- return new Report(type, variance, 0, DURATION_SCALE * DURATION_SCALE);
193
- }
194
- case 'sd':
195
- {
196
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);
197
- const { ssd } = computeStats(durations);
198
- const scaledVariance = ssd * SQRT_SCALE_SQ / BigInt(n - 1);
199
- const sdScaled = isqrt(scaledVariance);
200
- return new Report(type, sdScaled, 0, DURATION_SCALE * SQRT_SCALE);
201
- }
202
- case 'sem':
203
- {
204
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);
205
- const { ssd, n: nBig } = computeStats(durations);
206
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
207
- const semScaled = isqrt(semSqScaled);
208
- return new Report(type, semScaled, 0, DURATION_SCALE * SQRT_SCALE);
209
- }
210
- case 'moe':
211
- {
212
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);
213
- const { ssd, n: nBig } = computeStats(durations);
214
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
215
- const semScaled = isqrt(semSqScaled);
216
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
217
- return new Report(type, moeScaled, 0, DURATION_SCALE * SQRT_SCALE);
218
- }
219
- case 'rme':
220
- {
221
- if (n < 2) return new Report(type, 0n);
222
- const { mean, ssd, n: nBig } = computeStats(durations);
223
- if (mean === 0n) return new Report(type, 0n);
224
- const RME_PRECISION = 1_000_000n;
225
- const semOverMeanSqScaled = ssd * RME_PRECISION * RME_PRECISION / (BigInt(n - 1) * nBig * mean * mean);
226
- const semOverMeanScaled = isqrt(semOverMeanSqScaled);
227
- const rmeScaled = Z95_NUM * semOverMeanScaled * 100n / RME_PRECISION;
228
- return new Report(type, rmeScaled, 0, 100n);
229
- }
230
- case 'mad':
231
- {
232
- const medianIdx = Math.floor(n / 2);
233
- const median = n % 2 === 1 ? durations[medianIdx] : (durations[medianIdx - 1] + durations[medianIdx]) / 2n;
234
- const deviations = new BigUint64Array(n);
235
- for(let i = 0; i < n; i++){
236
- const diff = durations[i] > median ? durations[i] - median : median - durations[i];
237
- deviations[i] = diff;
238
- }
239
- deviations.sort();
240
- const madIdx = Math.floor(n / 2);
241
- const mad = n % 2 === 1 ? deviations[madIdx] : (deviations[madIdx - 1] + deviations[madIdx]) / 2n;
242
- return new Report(type, mad, 0, DURATION_SCALE);
243
- }
244
- case 'iqr':
245
- {
246
- const q1Idx = Math.floor(n * 0.25);
247
- const q3Idx = Math.floor(n * 0.75);
248
- const q1 = durations[q1Idx];
249
- const q3 = durations[q3Idx];
250
- const iqr = q3 - q1;
251
- return new Report(type, iqr, 0, DURATION_SCALE);
252
- }
253
- case 'ci_lower':
254
- {
255
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);
256
- const { mean, ssd, n: nBig } = computeStats(durations);
257
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
258
- const semScaled = isqrt(semSqScaled);
259
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
260
- const ciLowerScaled = mean * SQRT_SCALE - moeScaled;
261
- return new Report(type, ciLowerScaled > 0n ? ciLowerScaled : 0n, 0, DURATION_SCALE * SQRT_SCALE);
262
- }
263
- case 'ci_upper':
264
- {
265
- if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);
266
- const { mean, ssd, n: nBig } = computeStats(durations);
267
- const semSqScaled = ssd * SQRT_SCALE_SQ / (BigInt(n - 1) * nBig);
268
- const semScaled = isqrt(semSqScaled);
269
- const moeScaled = Z95_NUM * semScaled / Z95_DENOM;
270
- const ciUpperScaled = mean * SQRT_SCALE + moeScaled;
271
- return new Report(type, ciUpperScaled, 0, DURATION_SCALE * SQRT_SCALE);
272
- }
273
- default:
274
- {
275
- const p = Number(type.slice(1));
276
- if (p === 0) {
277
- return new Report(type, durations[0], 0, DURATION_SCALE);
278
- }
279
- if (p === 100) {
280
- return new Report(type, durations[n - 1], 0, DURATION_SCALE);
281
- }
282
- const idx = Math.ceil(p / 100 * n) - 1;
283
- const value = durations[Math.min(Math.max(idx, 0), n - 1)];
284
- const prev = idx > 0 ? durations[idx - 1] : value;
285
- const next = idx < n - 1 ? durations[idx + 1] : value;
286
- const gap = max(value - prev, next - value);
287
- const uncertainty = value > 0 ? Number(div(divs(gap, 2n, 100_00n), value)) / 100 : 0;
288
- return new Report(type, value, uncertainty, DURATION_SCALE);
289
- }
290
- }
291
- };
292
-
293
- //# sourceMappingURL=reporter.js.map