overtake 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/build/gc-watcher.cjs +5 -6
- package/build/gc-watcher.cjs.map +1 -1
- package/build/gc-watcher.d.ts +0 -1
- package/build/gc-watcher.js +5 -6
- package/build/gc-watcher.js.map +1 -1
- package/build/reporter.cjs +14 -13
- package/build/reporter.cjs.map +1 -1
- package/build/reporter.js +14 -13
- package/build/reporter.js.map +1 -1
- package/build/runner.cjs +267 -66
- package/build/runner.cjs.map +1 -1
- package/build/runner.js +268 -67
- package/build/runner.js.map +1 -1
- package/build/types.cjs +4 -0
- package/build/types.cjs.map +1 -1
- package/build/types.d.ts +2 -1
- package/build/types.js +1 -0
- package/build/types.js.map +1 -1
- package/build/worker.cjs +1 -1
- package/build/worker.cjs.map +1 -1
- package/build/worker.js +1 -1
- package/build/worker.js.map +1 -1
- package/examples/accuracy.ts +30 -5
- package/package.json +1 -1
- package/src/gc-watcher.ts +5 -6
- package/src/reporter.ts +14 -14
- package/src/runner.ts +327 -74
- package/src/types.ts +2 -1
- package/src/worker.ts +1 -1
package/build/gc-watcher.cjs
CHANGED
|
@@ -11,18 +11,17 @@ Object.defineProperty(exports, "GCWatcher", {
|
|
|
11
11
|
class GCWatcher {
|
|
12
12
|
#registry = new FinalizationRegistry(()=>{});
|
|
13
13
|
start() {
|
|
14
|
-
const
|
|
15
|
-
const ref = new WeakRef(
|
|
16
|
-
this.#registry.register(
|
|
14
|
+
const target = {};
|
|
15
|
+
const ref = new WeakRef(target);
|
|
16
|
+
this.#registry.register(target, null, ref);
|
|
17
17
|
return {
|
|
18
|
-
ref
|
|
19
|
-
token
|
|
18
|
+
ref
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
21
|
seen(marker) {
|
|
23
22
|
const collected = marker.ref.deref() === undefined;
|
|
24
23
|
if (!collected) {
|
|
25
|
-
this.#registry.unregister(marker.
|
|
24
|
+
this.#registry.unregister(marker.ref);
|
|
26
25
|
}
|
|
27
26
|
return collected;
|
|
28
27
|
}
|
package/build/gc-watcher.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gc-watcher.ts"],"sourcesContent":["export interface GCMarker {\n ref: WeakRef<object>;\n
|
|
1
|
+
{"version":3,"sources":["../src/gc-watcher.ts"],"sourcesContent":["export interface GCMarker {\n ref: WeakRef<object>;\n}\n\nexport class GCWatcher {\n #registry = new FinalizationRegistry(() => {});\n\n start(): GCMarker {\n const target = {};\n const ref = new WeakRef(target);\n this.#registry.register(target, null, ref);\n return { ref };\n }\n\n seen(marker: GCMarker): boolean {\n const collected = marker.ref.deref() === undefined;\n if (!collected) {\n this.#registry.unregister(marker.ref);\n }\n return collected;\n }\n}\n"],"names":["GCWatcher","FinalizationRegistry","start","target","ref","WeakRef","register","seen","marker","collected","deref","undefined","unregister"],"mappings":";;;;+BAIaA;;;eAAAA;;;AAAN,MAAMA;IACX,CAAA,QAAS,GAAG,IAAIC,qBAAqB,KAAO,GAAG;IAE/CC,QAAkB;QAChB,MAAMC,SAAS,CAAC;QAChB,MAAMC,MAAM,IAAIC,QAAQF;QACxB,IAAI,CAAC,CAAA,QAAS,CAACG,QAAQ,CAACH,QAAQ,MAAMC;QACtC,OAAO;YAAEA;QAAI;IACf;IAEAG,KAAKC,MAAgB,EAAW;QAC9B,MAAMC,YAAYD,OAAOJ,GAAG,CAACM,KAAK,OAAOC;QACzC,IAAI,CAACF,WAAW;YACd,IAAI,CAAC,CAAA,QAAS,CAACG,UAAU,CAACJ,OAAOJ,GAAG;QACtC;QACA,OAAOK;IACT;AACF"}
|
package/build/gc-watcher.d.ts
CHANGED
package/build/gc-watcher.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
export class GCWatcher {
|
|
2
2
|
#registry = new FinalizationRegistry(()=>{});
|
|
3
3
|
start() {
|
|
4
|
-
const
|
|
5
|
-
const ref = new WeakRef(
|
|
6
|
-
this.#registry.register(
|
|
4
|
+
const target = {};
|
|
5
|
+
const ref = new WeakRef(target);
|
|
6
|
+
this.#registry.register(target, null, ref);
|
|
7
7
|
return {
|
|
8
|
-
ref
|
|
9
|
-
token
|
|
8
|
+
ref
|
|
10
9
|
};
|
|
11
10
|
}
|
|
12
11
|
seen(marker) {
|
|
13
12
|
const collected = marker.ref.deref() === undefined;
|
|
14
13
|
if (!collected) {
|
|
15
|
-
this.#registry.unregister(marker.
|
|
14
|
+
this.#registry.unregister(marker.ref);
|
|
16
15
|
}
|
|
17
16
|
return collected;
|
|
18
17
|
}
|
package/build/gc-watcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gc-watcher.ts"],"sourcesContent":["export interface GCMarker {\n ref: WeakRef<object>;\n
|
|
1
|
+
{"version":3,"sources":["../src/gc-watcher.ts"],"sourcesContent":["export interface GCMarker {\n ref: WeakRef<object>;\n}\n\nexport class GCWatcher {\n #registry = new FinalizationRegistry(() => {});\n\n start(): GCMarker {\n const target = {};\n const ref = new WeakRef(target);\n this.#registry.register(target, null, ref);\n return { ref };\n }\n\n seen(marker: GCMarker): boolean {\n const collected = marker.ref.deref() === undefined;\n if (!collected) {\n this.#registry.unregister(marker.ref);\n }\n return collected;\n }\n}\n"],"names":["GCWatcher","FinalizationRegistry","start","target","ref","WeakRef","register","seen","marker","collected","deref","undefined","unregister"],"mappings":"AAIA,OAAO,MAAMA;IACX,CAAA,QAAS,GAAG,IAAIC,qBAAqB,KAAO,GAAG;IAE/CC,QAAkB;QAChB,MAAMC,SAAS,CAAC;QAChB,MAAMC,MAAM,IAAIC,QAAQF;QACxB,IAAI,CAAC,CAAA,QAAS,CAACG,QAAQ,CAACH,QAAQ,MAAMC;QACtC,OAAO;YAAEA;QAAI;IACf;IAEAG,KAAKC,MAAgB,EAAW;QAC9B,MAAMC,YAAYD,OAAOJ,GAAG,CAACM,KAAK,OAAOC;QACzC,IAAI,CAACF,WAAW;YACd,IAAI,CAAC,CAAA,QAAS,CAACG,UAAU,CAACJ,OAAOJ,GAAG;QACtC;QACA,OAAOK;IACT;AACF"}
|
package/build/reporter.cjs
CHANGED
|
@@ -17,6 +17,7 @@ _export(exports, {
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
const _utilscjs = require("./utils.cjs");
|
|
20
|
+
const _typescjs = require("./types.cjs");
|
|
20
21
|
const units = [
|
|
21
22
|
{
|
|
22
23
|
unit: 'ns',
|
|
@@ -91,17 +92,17 @@ const createReport = (durations, type)=>{
|
|
|
91
92
|
switch(type){
|
|
92
93
|
case 'min':
|
|
93
94
|
{
|
|
94
|
-
return new Report(type, durations[0]);
|
|
95
|
+
return new Report(type, durations[0], 0, _typescjs.DURATION_SCALE);
|
|
95
96
|
}
|
|
96
97
|
case 'max':
|
|
97
98
|
{
|
|
98
|
-
return new Report(type, durations[n - 1]);
|
|
99
|
+
return new Report(type, durations[n - 1], 0, _typescjs.DURATION_SCALE);
|
|
99
100
|
}
|
|
100
101
|
case 'median':
|
|
101
102
|
{
|
|
102
103
|
const mid = Math.floor(n / 2);
|
|
103
104
|
const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];
|
|
104
|
-
return new Report(type, med);
|
|
105
|
+
return new Report(type, med, 0, _typescjs.DURATION_SCALE);
|
|
105
106
|
}
|
|
106
107
|
case 'mode':
|
|
107
108
|
{
|
|
@@ -124,7 +125,7 @@ const createReport = (durations, type)=>{
|
|
|
124
125
|
if (lastIdx < n - 1) upper = durations[lastIdx + 1];
|
|
125
126
|
const gap = (0, _utilscjs.max)(modeVal - lower, upper - modeVal);
|
|
126
127
|
const uncertainty = modeVal > 0 ? Number(gap / 2n * 100n / modeVal) : 0;
|
|
127
|
-
return new Report(type, modeVal, uncertainty);
|
|
128
|
+
return new Report(type, modeVal, uncertainty, _typescjs.DURATION_SCALE);
|
|
128
129
|
}
|
|
129
130
|
case 'ops':
|
|
130
131
|
{
|
|
@@ -132,15 +133,15 @@ const createReport = (durations, type)=>{
|
|
|
132
133
|
for (const duration of durations){
|
|
133
134
|
sum += duration;
|
|
134
135
|
}
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
const raw = Number(
|
|
136
|
+
const avgScaled = sum / BigInt(n);
|
|
137
|
+
const nsPerSecScaled = 1_000_000_000n * _typescjs.DURATION_SCALE;
|
|
138
|
+
const raw = Number(nsPerSecScaled) / Number(avgScaled);
|
|
138
139
|
const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
|
|
139
140
|
const exp = raw > 100 ? 0 : 2 + extra;
|
|
140
141
|
const scale = 10n ** BigInt(exp);
|
|
141
|
-
const value =
|
|
142
|
+
const value = avgScaled > 0n ? nsPerSecScaled * scale / avgScaled : 0n;
|
|
142
143
|
const deviation = durations[n - 1] - durations[0];
|
|
143
|
-
const uncertainty =
|
|
144
|
+
const uncertainty = avgScaled > 0 ? Number((0, _utilscjs.div)(deviation * scale, 2n * avgScaled)) : 0;
|
|
144
145
|
return new Report(type, value, uncertainty, scale);
|
|
145
146
|
}
|
|
146
147
|
case 'mean':
|
|
@@ -150,16 +151,16 @@ const createReport = (durations, type)=>{
|
|
|
150
151
|
sum += duration;
|
|
151
152
|
}
|
|
152
153
|
const value = (0, _utilscjs.divs)(sum, BigInt(n), 1n);
|
|
153
|
-
return new Report(type, value);
|
|
154
|
+
return new Report(type, value, 0, _typescjs.DURATION_SCALE);
|
|
154
155
|
}
|
|
155
156
|
default:
|
|
156
157
|
{
|
|
157
158
|
const p = Number(type.slice(1));
|
|
158
159
|
if (p === 0) {
|
|
159
|
-
return new Report(type, durations[0]);
|
|
160
|
+
return new Report(type, durations[0], 0, _typescjs.DURATION_SCALE);
|
|
160
161
|
}
|
|
161
162
|
if (p === 100) {
|
|
162
|
-
return new Report(type, durations[n - 1]);
|
|
163
|
+
return new Report(type, durations[n - 1], 0, _typescjs.DURATION_SCALE);
|
|
163
164
|
}
|
|
164
165
|
const idx = Math.ceil(p / 100 * n) - 1;
|
|
165
166
|
const value = durations[Math.min(Math.max(idx, 0), n - 1)];
|
|
@@ -167,7 +168,7 @@ const createReport = (durations, type)=>{
|
|
|
167
168
|
const next = idx < n - 1 ? durations[idx + 1] : value;
|
|
168
169
|
const gap = (0, _utilscjs.max)(value - prev, next - value);
|
|
169
170
|
const uncertainty = value > 0 ? Number((0, _utilscjs.div)((0, _utilscjs.divs)(gap, 2n, 100_00n), value)) / 100 : 0;
|
|
170
|
-
return new Report(type, value, uncertainty);
|
|
171
|
+
return new Report(type, value, uncertainty, _typescjs.DURATION_SCALE);
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
};
|
package/build/reporter.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["import { div, max, divs } from './utils.js';\nimport { ReportType } 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 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\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]);\n }\n case 'max': {\n return new Report(type, durations[n - 1]);\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);\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);\n }\n\n case 'ops': {\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const
|
|
1
|
+
{"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["import { div, max, divs } 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 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\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 let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const avgScaled = sum / BigInt(n);\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 const deviation = durations[n - 1] - durations[0];\n const uncertainty = avgScaled > 0 ? Number(div(deviation * scale, 2n * avgScaled)) : 0;\n return new Report(type, value, uncertainty, scale);\n }\n case 'mean': {\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const value = divs(sum, BigInt(n), 1n);\n return new Report(type, value, 0, DURATION_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","u","candidate","durations","length","DURATION_SCALE","mid","Math","floor","med","freq","Map","maxCount","modeVal","d","count","get","set","lower","upper","firstIdx","indexOf","lastIdx","lastIndexOf","gap","max","sum","duration","avgScaled","BigInt","nsPerSecScaled","raw","extra","ceil","log10","exp","deviation","divs","p","slice","idx","min","prev","next"],"mappings":"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"}
|
package/build/reporter.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { div, max, divs } from "./utils.js";
|
|
2
|
+
import { DURATION_SCALE } from "./types.js";
|
|
2
3
|
const units = [
|
|
3
4
|
{
|
|
4
5
|
unit: 'ns',
|
|
@@ -73,17 +74,17 @@ export const createReport = (durations, type)=>{
|
|
|
73
74
|
switch(type){
|
|
74
75
|
case 'min':
|
|
75
76
|
{
|
|
76
|
-
return new Report(type, durations[0]);
|
|
77
|
+
return new Report(type, durations[0], 0, DURATION_SCALE);
|
|
77
78
|
}
|
|
78
79
|
case 'max':
|
|
79
80
|
{
|
|
80
|
-
return new Report(type, durations[n - 1]);
|
|
81
|
+
return new Report(type, durations[n - 1], 0, DURATION_SCALE);
|
|
81
82
|
}
|
|
82
83
|
case 'median':
|
|
83
84
|
{
|
|
84
85
|
const mid = Math.floor(n / 2);
|
|
85
86
|
const med = n % 2 === 0 ? (durations[mid - 1] + durations[mid]) / 2n : durations[mid];
|
|
86
|
-
return new Report(type, med);
|
|
87
|
+
return new Report(type, med, 0, DURATION_SCALE);
|
|
87
88
|
}
|
|
88
89
|
case 'mode':
|
|
89
90
|
{
|
|
@@ -106,7 +107,7 @@ export const createReport = (durations, type)=>{
|
|
|
106
107
|
if (lastIdx < n - 1) upper = durations[lastIdx + 1];
|
|
107
108
|
const gap = max(modeVal - lower, upper - modeVal);
|
|
108
109
|
const uncertainty = modeVal > 0 ? Number(gap / 2n * 100n / modeVal) : 0;
|
|
109
|
-
return new Report(type, modeVal, uncertainty);
|
|
110
|
+
return new Report(type, modeVal, uncertainty, DURATION_SCALE);
|
|
110
111
|
}
|
|
111
112
|
case 'ops':
|
|
112
113
|
{
|
|
@@ -114,15 +115,15 @@ export const createReport = (durations, type)=>{
|
|
|
114
115
|
for (const duration of durations){
|
|
115
116
|
sum += duration;
|
|
116
117
|
}
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const raw = Number(
|
|
118
|
+
const avgScaled = sum / BigInt(n);
|
|
119
|
+
const nsPerSecScaled = 1_000_000_000n * DURATION_SCALE;
|
|
120
|
+
const raw = Number(nsPerSecScaled) / Number(avgScaled);
|
|
120
121
|
const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
|
|
121
122
|
const exp = raw > 100 ? 0 : 2 + extra;
|
|
122
123
|
const scale = 10n ** BigInt(exp);
|
|
123
|
-
const value =
|
|
124
|
+
const value = avgScaled > 0n ? nsPerSecScaled * scale / avgScaled : 0n;
|
|
124
125
|
const deviation = durations[n - 1] - durations[0];
|
|
125
|
-
const uncertainty =
|
|
126
|
+
const uncertainty = avgScaled > 0 ? Number(div(deviation * scale, 2n * avgScaled)) : 0;
|
|
126
127
|
return new Report(type, value, uncertainty, scale);
|
|
127
128
|
}
|
|
128
129
|
case 'mean':
|
|
@@ -132,16 +133,16 @@ export const createReport = (durations, type)=>{
|
|
|
132
133
|
sum += duration;
|
|
133
134
|
}
|
|
134
135
|
const value = divs(sum, BigInt(n), 1n);
|
|
135
|
-
return new Report(type, value);
|
|
136
|
+
return new Report(type, value, 0, DURATION_SCALE);
|
|
136
137
|
}
|
|
137
138
|
default:
|
|
138
139
|
{
|
|
139
140
|
const p = Number(type.slice(1));
|
|
140
141
|
if (p === 0) {
|
|
141
|
-
return new Report(type, durations[0]);
|
|
142
|
+
return new Report(type, durations[0], 0, DURATION_SCALE);
|
|
142
143
|
}
|
|
143
144
|
if (p === 100) {
|
|
144
|
-
return new Report(type, durations[n - 1]);
|
|
145
|
+
return new Report(type, durations[n - 1], 0, DURATION_SCALE);
|
|
145
146
|
}
|
|
146
147
|
const idx = Math.ceil(p / 100 * n) - 1;
|
|
147
148
|
const value = durations[Math.min(Math.max(idx, 0), n - 1)];
|
|
@@ -149,7 +150,7 @@ export const createReport = (durations, type)=>{
|
|
|
149
150
|
const next = idx < n - 1 ? durations[idx + 1] : value;
|
|
150
151
|
const gap = max(value - prev, next - value);
|
|
151
152
|
const uncertainty = value > 0 ? Number(div(divs(gap, 2n, 100_00n), value)) / 100 : 0;
|
|
152
|
-
return new Report(type, value, uncertainty);
|
|
153
|
+
return new Report(type, value, uncertainty, DURATION_SCALE);
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
};
|
package/build/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["import { div, max, divs } from './utils.js';\nimport { ReportType } 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 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\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]);\n }\n case 'max': {\n return new Report(type, durations[n - 1]);\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);\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);\n }\n\n case 'ops': {\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const
|
|
1
|
+
{"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["import { div, max, divs } 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 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\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 let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const avgScaled = sum / BigInt(n);\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 const deviation = durations[n - 1] - durations[0];\n const uncertainty = avgScaled > 0 ? Number(div(deviation * scale, 2n * avgScaled)) : 0;\n return new Report(type, value, uncertainty, scale);\n }\n case 'mean': {\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const value = divs(sum, BigInt(n), 1n);\n return new Report(type, value, 0, DURATION_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":["div","max","divs","DURATION_SCALE","units","unit","factor","smartFixed","n","toLocaleString","undefined","minimumFractionDigits","maximumFractionDigits","useGrouping","Report","type","value","uncertainty","scale","valueOf","Number","toString","display","u","candidate","createReport","durations","length","mid","Math","floor","med","freq","Map","maxCount","modeVal","d","count","get","set","lower","upper","firstIdx","indexOf","lastIdx","lastIndexOf","gap","sum","duration","avgScaled","BigInt","nsPerSecScaled","raw","extra","ceil","log10","exp","deviation","p","slice","idx","min","prev","next"],"mappings":"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"}
|