overtake 1.4.0 → 2.0.1
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/README.md +4 -15
- package/build/cli.js +126 -125
- package/build/executor.d.ts +6 -2
- package/build/executor.js +59 -46
- package/build/gc-watcher.js +2 -6
- package/build/index.d.ts +10 -11
- package/build/index.js +153 -155
- package/build/register-hook.d.ts +1 -0
- package/build/register-hook.js +15 -0
- package/build/reporter.d.ts +10 -2
- package/build/reporter.js +176 -214
- package/build/runner.d.ts +1 -1
- package/build/runner.js +128 -119
- package/build/types.d.ts +6 -6
- package/build/types.js +9 -14
- package/build/utils.d.ts +1 -17
- package/build/utils.js +53 -85
- package/build/worker.js +25 -24
- package/package.json +7 -25
- package/src/__tests__/assert-no-closure.ts +135 -0
- package/src/__tests__/benchmark-execute.ts +48 -0
- package/src/cli.ts +137 -142
- package/src/executor.ts +45 -15
- package/src/index.ts +85 -57
- package/src/register-hook.ts +15 -0
- package/src/reporter.ts +26 -18
- package/src/runner.ts +1 -4
- package/src/types.ts +8 -8
- package/src/utils.ts +15 -54
- package/src/worker.ts +5 -2
- package/tsconfig.json +2 -1
- package/build/cli.cjs +0 -179
- package/build/cli.cjs.map +0 -1
- package/build/cli.js.map +0 -1
- package/build/executor.cjs +0 -123
- package/build/executor.cjs.map +0 -1
- package/build/executor.js.map +0 -1
- package/build/gc-watcher.cjs +0 -30
- package/build/gc-watcher.cjs.map +0 -1
- package/build/gc-watcher.js.map +0 -1
- package/build/index.cjs +0 -442
- package/build/index.cjs.map +0 -1
- package/build/index.js.map +0 -1
- package/build/reporter.cjs +0 -311
- package/build/reporter.cjs.map +0 -1
- package/build/reporter.js.map +0 -1
- package/build/runner.cjs +0 -532
- package/build/runner.cjs.map +0 -1
- package/build/runner.js.map +0 -1
- package/build/types.cjs +0 -66
- package/build/types.cjs.map +0 -1
- package/build/types.js.map +0 -1
- package/build/utils.cjs +0 -174
- package/build/utils.cjs.map +0 -1
- package/build/utils.js.map +0 -1
- package/build/worker.cjs +0 -155
- package/build/worker.cjs.map +0 -1
- package/build/worker.js.map +0 -1
- package/src/__tests__/assert-no-closure.js +0 -134
package/build/reporter.js
CHANGED
|
@@ -1,36 +1,18 @@
|
|
|
1
|
-
import { div, max, divs, isqrt } from
|
|
2
|
-
import { DURATION_SCALE } from
|
|
1
|
+
import { div, max, divs, isqrt } from './utils.js';
|
|
2
|
+
import { DURATION_SCALE } from './types.js';
|
|
3
3
|
const units = [
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
|
|
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
|
-
}
|
|
4
|
+
{ unit: 'ns', factor: 1 },
|
|
5
|
+
{ unit: 'µs', factor: 1e3 },
|
|
6
|
+
{ unit: 'ms', factor: 1e6 },
|
|
7
|
+
{ unit: 's', factor: 1e9 },
|
|
8
|
+
{ unit: 'm', factor: 60 * 1e9 },
|
|
9
|
+
{ unit: 'h', factor: 3600 * 1e9 },
|
|
28
10
|
];
|
|
29
11
|
function smartFixed(n) {
|
|
30
12
|
return n.toLocaleString(undefined, {
|
|
31
13
|
minimumFractionDigits: 0,
|
|
32
14
|
maximumFractionDigits: 2,
|
|
33
|
-
useGrouping: true
|
|
15
|
+
useGrouping: true,
|
|
34
16
|
});
|
|
35
17
|
}
|
|
36
18
|
export class Report {
|
|
@@ -38,7 +20,7 @@ export class Report {
|
|
|
38
20
|
value;
|
|
39
21
|
uncertainty;
|
|
40
22
|
scale;
|
|
41
|
-
constructor(type, value, uncertainty = 0, scale = 1n){
|
|
23
|
+
constructor(type, value, uncertainty = 0, scale = 1n) {
|
|
42
24
|
this.type = type;
|
|
43
25
|
this.value = value;
|
|
44
26
|
this.uncertainty = uncertainty;
|
|
@@ -60,20 +42,11 @@ export class Report {
|
|
|
60
42
|
let display = value;
|
|
61
43
|
let unit = 'ns²';
|
|
62
44
|
const varianceUnits = [
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
unit: 'µs²',
|
|
69
|
-
factor: 1e6
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
unit: 'ms²',
|
|
73
|
-
factor: 1e12
|
|
74
|
-
}
|
|
45
|
+
{ unit: 'ns²', factor: 1 },
|
|
46
|
+
{ unit: 'µs²', factor: 1e6 },
|
|
47
|
+
{ unit: 'ms²', factor: 1e12 },
|
|
75
48
|
];
|
|
76
|
-
for (const { unit: u, factor } of varianceUnits){
|
|
49
|
+
for (const { unit: u, factor } of varianceUnits) {
|
|
77
50
|
const candidate = value / factor;
|
|
78
51
|
if (candidate < 1000) {
|
|
79
52
|
display = candidate;
|
|
@@ -85,7 +58,7 @@ export class Report {
|
|
|
85
58
|
}
|
|
86
59
|
let display = value;
|
|
87
60
|
let unit = 'ns';
|
|
88
|
-
for (const { unit: u, factor } of units){
|
|
61
|
+
for (const { unit: u, factor } of units) {
|
|
89
62
|
const candidate = value / factor;
|
|
90
63
|
if (candidate < 1000) {
|
|
91
64
|
display = candidate;
|
|
@@ -96,198 +69,187 @@ export class Report {
|
|
|
96
69
|
return `${smartFixed(display)} ${unit}${uncertainty}`;
|
|
97
70
|
}
|
|
98
71
|
}
|
|
99
|
-
const SQRT_SCALE =
|
|
72
|
+
const SQRT_SCALE = 1000000n;
|
|
100
73
|
const SQRT_SCALE_SQ = SQRT_SCALE * SQRT_SCALE;
|
|
101
74
|
const Z95_NUM = 196n;
|
|
102
75
|
const Z95_DENOM = 100n;
|
|
103
|
-
const computeStats = (durations)=>{
|
|
76
|
+
export const computeStats = (durations) => {
|
|
104
77
|
let sum = 0n;
|
|
105
|
-
for (const d of durations)
|
|
78
|
+
for (const d of durations)
|
|
79
|
+
sum += d;
|
|
106
80
|
const n = BigInt(durations.length);
|
|
107
81
|
const mean = sum / n;
|
|
108
82
|
let ssd = 0n;
|
|
109
|
-
for (const d of durations){
|
|
83
|
+
for (const d of durations) {
|
|
110
84
|
const diff = d - mean;
|
|
111
85
|
ssd += diff * diff;
|
|
112
86
|
}
|
|
113
|
-
return {
|
|
114
|
-
sum,
|
|
115
|
-
mean,
|
|
116
|
-
ssd,
|
|
117
|
-
n
|
|
118
|
-
};
|
|
87
|
+
return { sum, mean, ssd, n };
|
|
119
88
|
};
|
|
120
|
-
export const createReport = (durations, type)=>{
|
|
89
|
+
export const createReport = (durations, type, stats) => {
|
|
121
90
|
const n = durations.length;
|
|
122
91
|
if (n === 0) {
|
|
123
92
|
return new Report(type, 0n);
|
|
124
93
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
case 'max':
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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);
|
|
94
|
+
const st = stats ?? computeStats(durations);
|
|
95
|
+
switch (type) {
|
|
96
|
+
case 'min': {
|
|
97
|
+
return new Report(type, durations[0], 0, DURATION_SCALE);
|
|
98
|
+
}
|
|
99
|
+
case 'max': {
|
|
100
|
+
return new Report(type, durations[n - 1], 0, DURATION_SCALE);
|
|
101
|
+
}
|
|
102
|
+
case 'median': {
|
|
103
|
+
const mid = Math.floor(n / 2);
|
|
104
|
+
const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];
|
|
105
|
+
return new Report(type, med, 0, DURATION_SCALE);
|
|
106
|
+
}
|
|
107
|
+
case 'mode': {
|
|
108
|
+
const freq = new Map();
|
|
109
|
+
let maxCount = 0n;
|
|
110
|
+
let modeVal = durations[0];
|
|
111
|
+
for (const d of durations) {
|
|
112
|
+
const count = (freq.get(d) || 0n) + 1n;
|
|
113
|
+
freq.set(d, count);
|
|
114
|
+
if (count > maxCount) {
|
|
115
|
+
maxCount = count;
|
|
116
|
+
modeVal = d;
|
|
178
117
|
}
|
|
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
118
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const RME_PRECISION =
|
|
225
|
-
const semOverMeanSqScaled = ssd * RME_PRECISION * RME_PRECISION / (BigInt(n - 1) * nBig *
|
|
119
|
+
let lower = modeVal;
|
|
120
|
+
let upper = modeVal;
|
|
121
|
+
const firstIdx = durations.indexOf(modeVal);
|
|
122
|
+
const lastIdx = durations.lastIndexOf(modeVal);
|
|
123
|
+
if (firstIdx > 0)
|
|
124
|
+
lower = durations[firstIdx - 1];
|
|
125
|
+
if (lastIdx < n - 1)
|
|
126
|
+
upper = durations[lastIdx + 1];
|
|
127
|
+
const gap = max(modeVal - lower, upper - modeVal);
|
|
128
|
+
const uncertainty = modeVal > 0 ? Number(((gap / 2n) * 100n) / modeVal) : 0;
|
|
129
|
+
return new Report(type, modeVal, uncertainty, DURATION_SCALE);
|
|
130
|
+
}
|
|
131
|
+
case 'ops': {
|
|
132
|
+
const { mean: avgScaled, ssd, n: nBig } = st;
|
|
133
|
+
const nsPerSecScaled = 1000000000n * DURATION_SCALE;
|
|
134
|
+
const raw = Number(nsPerSecScaled) / Number(avgScaled);
|
|
135
|
+
const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
|
|
136
|
+
const exp = raw > 100 ? 0 : 2 + extra;
|
|
137
|
+
const scale = 10n ** BigInt(exp);
|
|
138
|
+
const value = avgScaled > 0n ? (nsPerSecScaled * scale) / avgScaled : 0n;
|
|
139
|
+
let uncertainty = 0;
|
|
140
|
+
if (n >= 2 && avgScaled > 0n) {
|
|
141
|
+
const RME_PRECISION = 1000000n;
|
|
142
|
+
const semOverMeanSqScaled = (ssd * RME_PRECISION * RME_PRECISION) / (BigInt(n - 1) * nBig * avgScaled * avgScaled);
|
|
226
143
|
const semOverMeanScaled = isqrt(semOverMeanSqScaled);
|
|
227
|
-
|
|
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);
|
|
144
|
+
uncertainty = Number(Z95_NUM * semOverMeanScaled) / Number(RME_PRECISION);
|
|
262
145
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
146
|
+
return new Report(type, value, uncertainty, scale);
|
|
147
|
+
}
|
|
148
|
+
case 'mean': {
|
|
149
|
+
const { sum } = st;
|
|
150
|
+
const value = divs(sum, BigInt(n), 1n);
|
|
151
|
+
return new Report(type, value, 0, DURATION_SCALE);
|
|
152
|
+
}
|
|
153
|
+
case 'variance': {
|
|
154
|
+
if (n < 2)
|
|
155
|
+
return new Report(type, 0n, 0, DURATION_SCALE * DURATION_SCALE);
|
|
156
|
+
const { ssd } = st;
|
|
157
|
+
const variance = ssd / BigInt(n - 1);
|
|
158
|
+
return new Report(type, variance, 0, DURATION_SCALE * DURATION_SCALE);
|
|
159
|
+
}
|
|
160
|
+
case 'sd': {
|
|
161
|
+
if (n < 2)
|
|
162
|
+
return new Report(type, 0n, 0, DURATION_SCALE);
|
|
163
|
+
const { ssd } = st;
|
|
164
|
+
const scaledVariance = (ssd * SQRT_SCALE_SQ) / BigInt(n - 1);
|
|
165
|
+
const sdScaled = isqrt(scaledVariance);
|
|
166
|
+
return new Report(type, sdScaled, 0, DURATION_SCALE * SQRT_SCALE);
|
|
167
|
+
}
|
|
168
|
+
case 'sem': {
|
|
169
|
+
if (n < 2)
|
|
170
|
+
return new Report(type, 0n, 0, DURATION_SCALE);
|
|
171
|
+
const { ssd, n: nBig } = st;
|
|
172
|
+
const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);
|
|
173
|
+
const semScaled = isqrt(semSqScaled);
|
|
174
|
+
return new Report(type, semScaled, 0, DURATION_SCALE * SQRT_SCALE);
|
|
175
|
+
}
|
|
176
|
+
case 'moe': {
|
|
177
|
+
if (n < 2)
|
|
178
|
+
return new Report(type, 0n, 0, DURATION_SCALE);
|
|
179
|
+
const { ssd, n: nBig } = st;
|
|
180
|
+
const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);
|
|
181
|
+
const semScaled = isqrt(semSqScaled);
|
|
182
|
+
const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;
|
|
183
|
+
return new Report(type, moeScaled, 0, DURATION_SCALE * SQRT_SCALE);
|
|
184
|
+
}
|
|
185
|
+
case 'rme': {
|
|
186
|
+
if (n < 2)
|
|
187
|
+
return new Report(type, 0n);
|
|
188
|
+
const { mean, ssd, n: nBig } = st;
|
|
189
|
+
if (mean === 0n)
|
|
190
|
+
return new Report(type, 0n);
|
|
191
|
+
const RME_PRECISION = 1000000n;
|
|
192
|
+
const semOverMeanSqScaled = (ssd * RME_PRECISION * RME_PRECISION) / (BigInt(n - 1) * nBig * mean * mean);
|
|
193
|
+
const semOverMeanScaled = isqrt(semOverMeanSqScaled);
|
|
194
|
+
const rmeScaled = (Z95_NUM * semOverMeanScaled * 100n) / RME_PRECISION;
|
|
195
|
+
return new Report(type, rmeScaled, 0, 100n);
|
|
196
|
+
}
|
|
197
|
+
case 'mad': {
|
|
198
|
+
const medianIdx = Math.floor(n / 2);
|
|
199
|
+
const median = n % 2 === 1 ? durations[medianIdx] : (durations[medianIdx - 1] + durations[medianIdx]) / 2n;
|
|
200
|
+
const deviations = new BigUint64Array(n);
|
|
201
|
+
for (let i = 0; i < n; i++) {
|
|
202
|
+
const diff = durations[i] > median ? durations[i] - median : median - durations[i];
|
|
203
|
+
deviations[i] = diff;
|
|
204
|
+
}
|
|
205
|
+
deviations.sort();
|
|
206
|
+
const madIdx = Math.floor(n / 2);
|
|
207
|
+
const mad = n % 2 === 1 ? deviations[madIdx] : (deviations[madIdx - 1] + deviations[madIdx]) / 2n;
|
|
208
|
+
return new Report(type, mad, 0, DURATION_SCALE);
|
|
209
|
+
}
|
|
210
|
+
case 'iqr': {
|
|
211
|
+
const q1Idx = Math.floor(n * 0.25);
|
|
212
|
+
const q3Idx = Math.floor(n * 0.75);
|
|
213
|
+
const q1 = durations[q1Idx];
|
|
214
|
+
const q3 = durations[q3Idx];
|
|
215
|
+
const iqr = q3 - q1;
|
|
216
|
+
return new Report(type, iqr, 0, DURATION_SCALE);
|
|
217
|
+
}
|
|
218
|
+
case 'ci_lower': {
|
|
219
|
+
if (n < 2)
|
|
220
|
+
return new Report(type, 0n, 0, DURATION_SCALE);
|
|
221
|
+
const { mean, ssd, n: nBig } = st;
|
|
222
|
+
const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);
|
|
223
|
+
const semScaled = isqrt(semSqScaled);
|
|
224
|
+
const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;
|
|
225
|
+
const ciLowerScaled = mean * SQRT_SCALE - moeScaled;
|
|
226
|
+
return new Report(type, ciLowerScaled > 0n ? ciLowerScaled : 0n, 0, DURATION_SCALE * SQRT_SCALE);
|
|
227
|
+
}
|
|
228
|
+
case 'ci_upper': {
|
|
229
|
+
if (n < 2)
|
|
230
|
+
return new Report(type, 0n, 0, DURATION_SCALE);
|
|
231
|
+
const { mean, ssd, n: nBig } = st;
|
|
232
|
+
const semSqScaled = (ssd * SQRT_SCALE_SQ) / (BigInt(n - 1) * nBig);
|
|
233
|
+
const semScaled = isqrt(semSqScaled);
|
|
234
|
+
const moeScaled = (Z95_NUM * semScaled) / Z95_DENOM;
|
|
235
|
+
const ciUpperScaled = mean * SQRT_SCALE + moeScaled;
|
|
236
|
+
return new Report(type, ciUpperScaled, 0, DURATION_SCALE * SQRT_SCALE);
|
|
237
|
+
}
|
|
238
|
+
default: {
|
|
239
|
+
const p = Number(type.slice(1));
|
|
240
|
+
if (p === 0) {
|
|
241
|
+
return new Report(type, durations[0], 0, DURATION_SCALE);
|
|
272
242
|
}
|
|
273
|
-
|
|
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);
|
|
243
|
+
if (p === 100) {
|
|
244
|
+
return new Report(type, durations[n - 1], 0, DURATION_SCALE);
|
|
289
245
|
}
|
|
246
|
+
const idx = Math.ceil((p / 100) * n) - 1;
|
|
247
|
+
const value = durations[Math.min(Math.max(idx, 0), n - 1)];
|
|
248
|
+
const prev = idx > 0 ? durations[idx - 1] : value;
|
|
249
|
+
const next = idx < n - 1 ? durations[idx + 1] : value;
|
|
250
|
+
const gap = max(value - prev, next - value);
|
|
251
|
+
const uncertainty = value > 0 ? Number(div(divs(gap, 2n, 10000n), value)) / 100 : 0;
|
|
252
|
+
return new Report(type, value, uncertainty, DURATION_SCALE);
|
|
253
|
+
}
|
|
290
254
|
}
|
|
291
255
|
};
|
|
292
|
-
|
|
293
|
-
//# sourceMappingURL=reporter.js.map
|
package/build/runner.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Options } from './types.js';
|
|
1
|
+
import { type Options } from './types.js';
|
|
2
2
|
export declare const benchmark: <TContext, TInput>({ setup, teardown, pre, run: runRaw, post, data, warmupCycles, minCycles, absThreshold, relThreshold, gcObserver, durationsSAB, controlSAB, }: Required<Options<TContext, TInput>>) => Promise<number>;
|