overtake 1.3.2 → 1.4.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.
- package/README.md +8 -0
- package/build/executor.cjs +12 -5
- package/build/executor.cjs.map +1 -1
- package/build/executor.d.ts +1 -0
- package/build/executor.js +13 -6
- package/build/executor.js.map +1 -1
- package/build/index.cjs +58 -16
- package/build/index.cjs.map +1 -1
- package/build/index.js +58 -16
- package/build/index.js.map +1 -1
- package/build/reporter.cjs +63 -116
- package/build/reporter.cjs.map +1 -1
- package/build/reporter.js +65 -118
- package/build/reporter.js.map +1 -1
- package/build/runner.cjs +23 -19
- package/build/runner.cjs.map +1 -1
- package/build/runner.js +23 -19
- package/build/runner.js.map +1 -1
- package/build/types.cjs +1 -1
- package/build/types.cjs.map +1 -1
- package/build/types.d.ts +1 -1
- package/build/types.js +1 -1
- package/build/types.js.map +1 -1
- package/build/utils.cjs +53 -0
- package/build/utils.cjs.map +1 -1
- package/build/utils.d.ts +2 -0
- package/build/utils.js +48 -1
- package/build/utils.js.map +1 -1
- package/build/worker.cjs +6 -9
- package/build/worker.cjs.map +1 -1
- package/build/worker.js +7 -10
- package/build/worker.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/assert-no-closure.js +134 -0
- package/src/executor.ts +12 -7
- package/src/index.ts +50 -11
- package/src/reporter.ts +62 -118
- package/src/runner.ts +26 -20
- package/src/types.ts +1 -1
- package/src/utils.ts +56 -1
- package/src/worker.ts +7 -9
package/build/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { cpus } from 'node:os';
|
|
|
2
2
|
import Progress from 'progress';
|
|
3
3
|
import { createExecutor } from "./executor.js";
|
|
4
4
|
import { DEFAULT_CYCLES } from "./types.js";
|
|
5
|
-
export const DEFAULT_WORKERS = cpus().length;
|
|
5
|
+
export const DEFAULT_WORKERS = Math.max(1, Math.ceil(cpus().length / 4));
|
|
6
6
|
export const AsyncFunction = (async ()=>{}).constructor;
|
|
7
7
|
const BENCHMARK_URL = Symbol.for('overtake.benchmarkUrl');
|
|
8
8
|
export const DEFAULT_REPORT_TYPES = [
|
|
@@ -186,7 +186,11 @@ export const printSimpleReports = (reports)=>{
|
|
|
186
186
|
for (const { measure, feeds } of report.measures){
|
|
187
187
|
console.group('\n', report.target, measure);
|
|
188
188
|
for (const { feed, data } of feeds){
|
|
189
|
-
const { count, heapUsedKB, dceWarning, ...metrics } = data;
|
|
189
|
+
const { count, heapUsedKB, dceWarning, error: benchError, ...metrics } = data;
|
|
190
|
+
if (benchError) {
|
|
191
|
+
console.log(feed, `\x1b[31m[error: ${benchError}]\x1b[0m`);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
190
194
|
const output = Object.entries(metrics).map(([key, report])=>`${key}: ${report.toString()}`).join('; ');
|
|
191
195
|
const extras = [];
|
|
192
196
|
if (heapUsedKB) extras.push(`heap: ${heapUsedKB}KB`);
|
|
@@ -204,10 +208,17 @@ export const printTableReports = (reports)=>{
|
|
|
204
208
|
console.log('\n', report.target, measure);
|
|
205
209
|
const table = {};
|
|
206
210
|
for (const { feed, data } of feeds){
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
+
const { error: benchError } = data;
|
|
212
|
+
if (benchError) {
|
|
213
|
+
table[feed] = {
|
|
214
|
+
error: benchError
|
|
215
|
+
};
|
|
216
|
+
} else {
|
|
217
|
+
table[feed] = Object.fromEntries(Object.entries(data).map(([key, report])=>[
|
|
218
|
+
key,
|
|
219
|
+
report.toString()
|
|
220
|
+
]));
|
|
221
|
+
}
|
|
211
222
|
}
|
|
212
223
|
console.table(table);
|
|
213
224
|
}
|
|
@@ -219,10 +230,17 @@ export const printJSONReports = (reports, padding)=>{
|
|
|
219
230
|
for (const { measure, feeds } of report.measures){
|
|
220
231
|
const row = {};
|
|
221
232
|
for (const { feed, data } of feeds){
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
const { error: benchError } = data;
|
|
234
|
+
if (benchError) {
|
|
235
|
+
row[feed] = {
|
|
236
|
+
error: String(benchError)
|
|
237
|
+
};
|
|
238
|
+
} else {
|
|
239
|
+
row[feed] = Object.fromEntries(Object.entries(data).map(([key, report])=>[
|
|
240
|
+
key,
|
|
241
|
+
report.toString()
|
|
242
|
+
]));
|
|
243
|
+
}
|
|
226
244
|
}
|
|
227
245
|
output[`${report.target} ${measure}`] = row;
|
|
228
246
|
}
|
|
@@ -234,7 +252,14 @@ export const printMarkdownReports = (reports)=>{
|
|
|
234
252
|
for (const { measure, feeds } of report.measures){
|
|
235
253
|
console.log(`\n## ${report.target} - ${measure}\n`);
|
|
236
254
|
if (feeds.length === 0) continue;
|
|
237
|
-
const
|
|
255
|
+
const firstValid = feeds.find((f)=>!f.data.error);
|
|
256
|
+
if (!firstValid) {
|
|
257
|
+
for (const { feed, data } of feeds){
|
|
258
|
+
console.log(`| ${feed} | error: ${data.error} |`);
|
|
259
|
+
}
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
const keys = Object.keys(firstValid.data).filter((k)=>k !== 'count' && k !== 'error');
|
|
238
263
|
const header = [
|
|
239
264
|
'Feed',
|
|
240
265
|
...keys
|
|
@@ -246,6 +271,10 @@ export const printMarkdownReports = (reports)=>{
|
|
|
246
271
|
console.log(`| ${header} |`);
|
|
247
272
|
console.log(`| ${separator} |`);
|
|
248
273
|
for (const { feed, data } of feeds){
|
|
274
|
+
if (data.error) {
|
|
275
|
+
console.log(`| ${feed} | error: ${data.error} |`);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
249
278
|
const values = keys.map((k)=>data[k]?.toString() ?? '-');
|
|
250
279
|
console.log(`| ${[
|
|
251
280
|
feed,
|
|
@@ -260,16 +289,24 @@ export const printHistogramReports = (reports, width = 40)=>{
|
|
|
260
289
|
for (const { measure, feeds } of report.measures){
|
|
261
290
|
console.log(`\n${report.target} - ${measure}\n`);
|
|
262
291
|
const opsKey = 'ops';
|
|
263
|
-
const values = feeds.map((f)=>
|
|
292
|
+
const values = feeds.map((f)=>{
|
|
293
|
+
const { error: benchError } = f.data;
|
|
294
|
+
return {
|
|
264
295
|
feed: f.feed,
|
|
265
|
-
value: f.data[opsKey]?.valueOf() ?? 0
|
|
266
|
-
|
|
296
|
+
value: benchError ? 0 : f.data[opsKey]?.valueOf() ?? 0,
|
|
297
|
+
error: benchError
|
|
298
|
+
};
|
|
299
|
+
});
|
|
267
300
|
const maxValue = Math.max(...values.map((v)=>v.value));
|
|
268
301
|
const maxLabelLen = Math.max(...values.map((v)=>v.feed.length));
|
|
269
|
-
for (const { feed, value } of values){
|
|
302
|
+
for (const { feed, value, error } of values){
|
|
303
|
+
const label = feed.padEnd(maxLabelLen);
|
|
304
|
+
if (error) {
|
|
305
|
+
console.log(` ${label} | \x1b[31m[error: ${error}]\x1b[0m`);
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
270
308
|
const barLen = maxValue > 0 ? Math.round(value / maxValue * width) : 0;
|
|
271
309
|
const bar = '\u2588'.repeat(barLen);
|
|
272
|
-
const label = feed.padEnd(maxLabelLen);
|
|
273
310
|
const formatted = value.toLocaleString('en-US', {
|
|
274
311
|
maximumFractionDigits: 2
|
|
275
312
|
});
|
|
@@ -283,6 +320,7 @@ export const reportsToBaseline = (reports)=>{
|
|
|
283
320
|
for (const report of reports){
|
|
284
321
|
for (const { measure, feeds } of report.measures){
|
|
285
322
|
for (const { feed, data } of feeds){
|
|
323
|
+
if (data.error) continue;
|
|
286
324
|
const key = `${report.target}/${measure}/${feed}`;
|
|
287
325
|
results[key] = {};
|
|
288
326
|
for (const [metric, value] of Object.entries(data)){
|
|
@@ -307,6 +345,10 @@ export const printComparisonReports = (reports, baseline, threshold = 5)=>{
|
|
|
307
345
|
const key = `${report.target}/${measure}/${feed}`;
|
|
308
346
|
const baselineData = baseline.results[key];
|
|
309
347
|
console.log(` ${feed}:`);
|
|
348
|
+
if (data.error) {
|
|
349
|
+
console.log(` \x1b[31m[error: ${data.error}]\x1b[0m`);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
310
352
|
for (const [metric, value] of Object.entries(data)){
|
|
311
353
|
if (metric === 'count') continue;
|
|
312
354
|
const current = value.valueOf();
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { cpus } from 'node:os';\nimport Progress from 'progress';\nimport { createExecutor, ExecutorOptions, ExecutorReport } from './executor.js';\nimport { MaybePromise, StepFn, SetupFn, TeardownFn, FeedFn, ReportType, ReportTypeList, DEFAULT_CYCLES, ProgressInfo } from './types.js';\n\ndeclare global {\n const benchmark: typeof Benchmark.create;\n}\n\nexport const DEFAULT_WORKERS = cpus().length;\n\nexport const AsyncFunction = (async () => {}).constructor;\nconst BENCHMARK_URL = Symbol.for('overtake.benchmarkUrl');\n\nexport interface TargetReport<R extends ReportTypeList> {\n target: string;\n measures: MeasureReport<R>[];\n}\n\nexport interface MeasureReport<R extends ReportTypeList> {\n measure: string;\n feeds: FeedReport<R>[];\n}\n\nexport interface FeedReport<R extends ReportTypeList> {\n feed: string;\n data: ExecutorReport<R>;\n}\n\nexport const DEFAULT_REPORT_TYPES = ['ops'] as const;\nexport type DefaultReportTypes = (typeof DEFAULT_REPORT_TYPES)[number];\n\nexport class MeasureContext<TContext, TInput> {\n public pre?: StepFn<TContext, TInput>;\n public post?: StepFn<TContext, TInput>;\n\n constructor(\n public title: string,\n public run: StepFn<TContext, TInput>,\n ) {}\n}\n\nexport class Measure<TContext, TInput> {\n #ctx: MeasureContext<TContext, TInput>;\n\n constructor(ctx: MeasureContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n\n pre(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.pre = fn;\n return this;\n }\n post(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.post = fn;\n return this;\n }\n}\n\nexport class TargetContext<TContext, TInput> {\n public teardown?: TeardownFn<TContext>;\n public measures: MeasureContext<TContext, TInput>[] = [];\n\n constructor(\n readonly title: string,\n readonly setup?: SetupFn<MaybePromise<TContext>>,\n ) {}\n}\n\nexport class Target<TContext, TInput> {\n #ctx: TargetContext<TContext, TInput>;\n\n constructor(ctx: TargetContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n teardown(fn: TeardownFn<TContext>): Target<TContext, TInput> {\n this.#ctx.teardown = fn;\n\n return this;\n }\n measure(title: string, run: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n const measure = new MeasureContext(title, run);\n this.#ctx.measures.push(measure);\n\n return new Measure(measure);\n }\n}\n\nexport class FeedContext<TInput> {\n constructor(\n readonly title: string,\n readonly fn?: FeedFn<TInput>,\n ) {}\n}\n\nexport class Benchmark<TInput> {\n #targets: TargetContext<unknown, TInput>[] = [];\n #feeds: FeedContext<TInput>[] = [];\n #executed = false;\n\n static create(title: string): Benchmark<void>;\n static create<I>(title: string, fn: FeedFn<I>): Benchmark<I>;\n static create<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<I> {\n if (fn) {\n return new Benchmark(title, fn);\n } else {\n return new Benchmark(title);\n }\n }\n\n constructor(title: string);\n constructor(title: string, fn: FeedFn<TInput>);\n constructor(title: string, fn?: FeedFn<TInput> | undefined) {\n if (fn) {\n this.feed(title, fn);\n } else {\n this.feed(title);\n }\n }\n\n feed(title: string): Benchmark<TInput | void>;\n feed<I>(title: string, fn: FeedFn<I>): Benchmark<TInput | I>;\n feed<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<TInput | I> {\n const self = this as Benchmark<TInput | I>;\n self.#feeds.push(fn ? new FeedContext(title, fn) : new FeedContext(title));\n\n return self;\n }\n\n target<TContext>(title: string): Target<void, TInput>;\n target<TContext>(title: string, setup: SetupFn<Awaited<TContext>>): Target<TContext, TInput>;\n target<TContext>(title: string, setup?: SetupFn<Awaited<TContext>> | undefined): Target<TContext, TInput> {\n const target = new TargetContext<TContext, TInput>(title, setup);\n this.#targets.push(target as TargetContext<unknown, TInput>);\n\n return new Target<TContext, TInput>(target);\n }\n\n async execute<R extends readonly ReportType[] = typeof DEFAULT_REPORT_TYPES>(options: ExecutorOptions<R> & { progress?: boolean }): Promise<TargetReport<R>[]> {\n const {\n workers = DEFAULT_WORKERS,\n warmupCycles = 20,\n maxCycles = DEFAULT_CYCLES,\n minCycles = 50,\n absThreshold = 1_000,\n relThreshold = 0.02,\n gcObserver = true,\n reportTypes = DEFAULT_REPORT_TYPES as unknown as R,\n progress = false,\n progressInterval = 100,\n } = options;\n if (this.#executed) {\n throw new Error(\"Benchmark is executed and can't be reused\");\n }\n this.#executed = true;\n const benchmarkUrl = (options as unknown as Record<symbol, unknown>)[BENCHMARK_URL];\n\n const totalBenchmarks = this.#targets.reduce((acc, t) => acc + t.measures.length * this.#feeds.length, 0);\n const progressMap = new Map<string, number>();\n let completedBenchmarks = 0;\n let bar: Progress | null = null;\n\n if (progress && totalBenchmarks > 0) {\n bar = new Progress(' [:bar] :percent :current/:total :label', {\n total: totalBenchmarks * 100,\n width: 30,\n complete: '=',\n incomplete: ' ',\n });\n }\n\n const onProgress = progress\n ? (info: ProgressInfo) => {\n progressMap.set(info.id, info.progress);\n const totalProgress = (completedBenchmarks + [...progressMap.values()].reduce((a, b) => a + b, 0)) * 100;\n const label = info.id.length > 30 ? info.id.slice(0, 27) + '...' : info.id;\n bar?.update(totalProgress / (totalBenchmarks * 100), { label });\n }\n : undefined;\n\n const executor = createExecutor<unknown, TInput, R>({\n workers,\n warmupCycles,\n maxCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver,\n reportTypes,\n onProgress,\n progressInterval,\n [BENCHMARK_URL]: benchmarkUrl,\n } as Required<ExecutorOptions<R>>);\n\n const reports: TargetReport<R>[] = [];\n for (const target of this.#targets) {\n const targetReport: TargetReport<R> = { target: target.title, measures: [] };\n for (const measure of target.measures) {\n const measureReport: MeasureReport<R> = { measure: measure.title, feeds: [] };\n for (const feed of this.#feeds) {\n const id = `${target.title}/${measure.title}/${feed.title}`;\n const data = await feed.fn?.();\n executor\n .push<ExecutorReport<R>>({\n id,\n setup: target.setup,\n teardown: target.teardown,\n pre: measure.pre,\n run: measure.run,\n post: measure.post,\n data,\n })\n .then((data) => {\n progressMap.delete(id);\n completedBenchmarks++;\n measureReport.feeds.push({\n feed: feed.title,\n data,\n });\n });\n }\n targetReport.measures.push(measureReport);\n }\n reports.push(targetReport);\n }\n await executor.drain();\n executor.kill();\n\n if (bar) {\n bar.update(1, { label: 'done' });\n bar.terminate();\n }\n\n return reports;\n }\n}\n\nexport const printSimpleReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.group('\\n', report.target, measure);\n for (const { feed, data } of feeds) {\n const { count, heapUsedKB, dceWarning, ...metrics } = data as Record<string, unknown>;\n const output = Object.entries(metrics)\n .map(([key, report]) => `${key}: ${(report as { toString(): string }).toString()}`)\n .join('; ');\n const extras: string[] = [];\n if (heapUsedKB) extras.push(`heap: ${heapUsedKB}KB`);\n if (dceWarning) extras.push('\\x1b[33m[DCE warning]\\x1b[0m');\n const extrasStr = extras.length > 0 ? ` (${extras.join(', ')})` : '';\n console.log(feed, output + extrasStr);\n }\n console.groupEnd();\n }\n }\n};\n\nexport const printTableReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log('\\n', report.target, measure);\n const table: Record<string, unknown> = {};\n for (const { feed, data } of feeds) {\n table[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n console.table(table);\n }\n }\n};\n\nexport const printJSONReports = <R extends ReportTypeList>(reports: TargetReport<R>[], padding?: number) => {\n const output = {} as Record<string, Record<string, Record<string, string>>>;\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n const row = {} as Record<string, Record<string, string>>;\n for (const { feed, data } of feeds) {\n row[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n output[`${report.target} ${measure}`] = row;\n }\n }\n console.log(JSON.stringify(output, null, padding));\n};\n\nexport const printMarkdownReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n## ${report.target} - ${measure}\\n`);\n if (feeds.length === 0) continue;\n\n const keys = Object.keys(feeds[0].data).filter((k) => k !== 'count');\n const header = ['Feed', ...keys].join(' | ');\n const separator = ['---', ...keys.map(() => '---')].join(' | ');\n\n console.log(`| ${header} |`);\n console.log(`| ${separator} |`);\n\n for (const { feed, data } of feeds) {\n const values = keys.map((k) => (data as Record<string, { toString(): string }>)[k]?.toString() ?? '-');\n console.log(`| ${[feed, ...values].join(' | ')} |`);\n }\n }\n }\n};\n\nexport const printHistogramReports = <R extends ReportTypeList>(reports: TargetReport<R>[], width = 40) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n${report.target} - ${measure}\\n`);\n\n const opsKey = 'ops';\n const values = feeds.map((f) => ({\n feed: f.feed,\n value: (f.data as Record<string, { valueOf(): number }>)[opsKey]?.valueOf() ?? 0,\n }));\n\n const maxValue = Math.max(...values.map((v) => v.value));\n const maxLabelLen = Math.max(...values.map((v) => v.feed.length));\n\n for (const { feed, value } of values) {\n const barLen = maxValue > 0 ? Math.round((value / maxValue) * width) : 0;\n const bar = '\\u2588'.repeat(barLen);\n const label = feed.padEnd(maxLabelLen);\n const formatted = value.toLocaleString('en-US', { maximumFractionDigits: 2 });\n console.log(` ${label} | ${bar} ${formatted} ops/s`);\n }\n }\n }\n};\n\nexport interface BaselineData {\n version: number;\n timestamp: string;\n results: Record<string, Record<string, number>>;\n}\n\nexport const reportsToBaseline = <R extends ReportTypeList>(reports: TargetReport<R>[]): BaselineData => {\n const results: Record<string, Record<string, number>> = {};\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n for (const { feed, data } of feeds) {\n const key = `${report.target}/${measure}/${feed}`;\n results[key] = {};\n for (const [metric, value] of Object.entries(data)) {\n if (metric !== 'count' && typeof (value as { valueOf(): number }).valueOf === 'function') {\n results[key][metric] = (value as { valueOf(): number }).valueOf();\n }\n }\n }\n }\n }\n return {\n version: 1,\n timestamp: new Date().toISOString(),\n results,\n };\n};\n\nexport const printComparisonReports = <R extends ReportTypeList>(reports: TargetReport<R>[], baseline: BaselineData, threshold = 5) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n${report.target} - ${measure}\\n`);\n\n for (const { feed, data } of feeds) {\n const key = `${report.target}/${measure}/${feed}`;\n const baselineData = baseline.results[key];\n\n console.log(` ${feed}:`);\n\n for (const [metric, value] of Object.entries(data)) {\n if (metric === 'count') continue;\n const current = (value as { valueOf(): number }).valueOf();\n const baselineValue = baselineData?.[metric];\n\n if (baselineValue !== undefined && baselineValue !== 0) {\n const change = ((current - baselineValue) / baselineValue) * 100;\n const isOps = metric === 'ops';\n const improved = isOps ? change > threshold : change < -threshold;\n const regressed = isOps ? change < -threshold : change > threshold;\n\n let indicator = ' ';\n if (improved) indicator = '\\x1b[32m+\\x1b[0m';\n else if (regressed) indicator = '\\x1b[31m!\\x1b[0m';\n\n const changeStr = change >= 0 ? `+${change.toFixed(1)}%` : `${change.toFixed(1)}%`;\n const coloredChange = regressed ? `\\x1b[31m${changeStr}\\x1b[0m` : improved ? `\\x1b[32m${changeStr}\\x1b[0m` : changeStr;\n\n console.log(` ${indicator} ${metric}: ${(value as { toString(): string }).toString()} (${coloredChange})`);\n } else {\n console.log(` * ${metric}: ${(value as { toString(): string }).toString()} (new)`);\n }\n }\n }\n }\n }\n\n console.log(`\\nBaseline from: ${baseline.timestamp}`);\n};\n"],"names":["cpus","Progress","createExecutor","DEFAULT_CYCLES","DEFAULT_WORKERS","length","AsyncFunction","BENCHMARK_URL","Symbol","for","DEFAULT_REPORT_TYPES","MeasureContext","pre","post","title","run","Measure","ctx","fn","TargetContext","teardown","measures","setup","Target","measure","push","FeedContext","Benchmark","create","feed","self","target","execute","options","workers","warmupCycles","maxCycles","minCycles","absThreshold","relThreshold","gcObserver","reportTypes","progress","progressInterval","Error","benchmarkUrl","totalBenchmarks","reduce","acc","t","progressMap","Map","completedBenchmarks","bar","total","width","complete","incomplete","onProgress","info","set","id","totalProgress","values","a","b","label","slice","update","undefined","executor","reports","targetReport","measureReport","feeds","data","then","delete","drain","kill","terminate","printSimpleReports","report","console","group","count","heapUsedKB","dceWarning","metrics","output","Object","entries","map","key","toString","join","extras","extrasStr","log","groupEnd","printTableReports","table","fromEntries","printJSONReports","padding","row","JSON","stringify","printMarkdownReports","keys","filter","k","header","separator","printHistogramReports","opsKey","f","value","valueOf","maxValue","Math","max","v","maxLabelLen","barLen","round","repeat","padEnd","formatted","toLocaleString","maximumFractionDigits","reportsToBaseline","results","metric","version","timestamp","Date","toISOString","printComparisonReports","baseline","threshold","baselineData","current","baselineValue","change","isOps","improved","regressed","indicator","changeStr","toFixed","coloredChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { cpus } from 'node:os';\nimport Progress from 'progress';\nimport { createExecutor, ExecutorOptions, ExecutorReport } from './executor.js';\nimport { MaybePromise, StepFn, SetupFn, TeardownFn, FeedFn, ReportType, ReportTypeList, DEFAULT_CYCLES, ProgressInfo } from './types.js';\n\ndeclare global {\n const benchmark: typeof Benchmark.create;\n}\n\nexport const DEFAULT_WORKERS = Math.max(1, Math.ceil(cpus().length / 4));\n\nexport const AsyncFunction = (async () => {}).constructor;\nconst BENCHMARK_URL = Symbol.for('overtake.benchmarkUrl');\n\nexport interface TargetReport<R extends ReportTypeList> {\n target: string;\n measures: MeasureReport<R>[];\n}\n\nexport interface MeasureReport<R extends ReportTypeList> {\n measure: string;\n feeds: FeedReport<R>[];\n}\n\nexport interface FeedReport<R extends ReportTypeList> {\n feed: string;\n data: ExecutorReport<R>;\n}\n\nexport const DEFAULT_REPORT_TYPES = ['ops'] as const;\nexport type DefaultReportTypes = (typeof DEFAULT_REPORT_TYPES)[number];\n\nexport class MeasureContext<TContext, TInput> {\n public pre?: StepFn<TContext, TInput>;\n public post?: StepFn<TContext, TInput>;\n\n constructor(\n public title: string,\n public run: StepFn<TContext, TInput>,\n ) {}\n}\n\nexport class Measure<TContext, TInput> {\n #ctx: MeasureContext<TContext, TInput>;\n\n constructor(ctx: MeasureContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n\n pre(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.pre = fn;\n return this;\n }\n post(fn: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n this.#ctx.post = fn;\n return this;\n }\n}\n\nexport class TargetContext<TContext, TInput> {\n public teardown?: TeardownFn<TContext>;\n public measures: MeasureContext<TContext, TInput>[] = [];\n\n constructor(\n readonly title: string,\n readonly setup?: SetupFn<MaybePromise<TContext>>,\n ) {}\n}\n\nexport class Target<TContext, TInput> {\n #ctx: TargetContext<TContext, TInput>;\n\n constructor(ctx: TargetContext<TContext, TInput>) {\n this.#ctx = ctx;\n }\n teardown(fn: TeardownFn<TContext>): Target<TContext, TInput> {\n this.#ctx.teardown = fn;\n\n return this;\n }\n measure(title: string, run: StepFn<TContext, TInput>): Measure<TContext, TInput> {\n const measure = new MeasureContext(title, run);\n this.#ctx.measures.push(measure);\n\n return new Measure(measure);\n }\n}\n\nexport class FeedContext<TInput> {\n constructor(\n readonly title: string,\n readonly fn?: FeedFn<TInput>,\n ) {}\n}\n\nexport class Benchmark<TInput> {\n #targets: TargetContext<unknown, TInput>[] = [];\n #feeds: FeedContext<TInput>[] = [];\n #executed = false;\n\n static create(title: string): Benchmark<void>;\n static create<I>(title: string, fn: FeedFn<I>): Benchmark<I>;\n static create<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<I> {\n if (fn) {\n return new Benchmark(title, fn);\n } else {\n return new Benchmark(title);\n }\n }\n\n constructor(title: string);\n constructor(title: string, fn: FeedFn<TInput>);\n constructor(title: string, fn?: FeedFn<TInput> | undefined) {\n if (fn) {\n this.feed(title, fn);\n } else {\n this.feed(title);\n }\n }\n\n feed(title: string): Benchmark<TInput | void>;\n feed<I>(title: string, fn: FeedFn<I>): Benchmark<TInput | I>;\n feed<I>(title: string, fn?: FeedFn<I> | undefined): Benchmark<TInput | I> {\n const self = this as Benchmark<TInput | I>;\n self.#feeds.push(fn ? new FeedContext(title, fn) : new FeedContext(title));\n\n return self;\n }\n\n target<TContext>(title: string): Target<void, TInput>;\n target<TContext>(title: string, setup: SetupFn<Awaited<TContext>>): Target<TContext, TInput>;\n target<TContext>(title: string, setup?: SetupFn<Awaited<TContext>> | undefined): Target<TContext, TInput> {\n const target = new TargetContext<TContext, TInput>(title, setup);\n this.#targets.push(target as TargetContext<unknown, TInput>);\n\n return new Target<TContext, TInput>(target);\n }\n\n async execute<R extends readonly ReportType[] = typeof DEFAULT_REPORT_TYPES>(options: ExecutorOptions<R> & { progress?: boolean }): Promise<TargetReport<R>[]> {\n const {\n workers = DEFAULT_WORKERS,\n warmupCycles = 20,\n maxCycles = DEFAULT_CYCLES,\n minCycles = 50,\n absThreshold = 1_000,\n relThreshold = 0.02,\n gcObserver = true,\n reportTypes = DEFAULT_REPORT_TYPES as unknown as R,\n progress = false,\n progressInterval = 100,\n } = options;\n if (this.#executed) {\n throw new Error(\"Benchmark is executed and can't be reused\");\n }\n this.#executed = true;\n const benchmarkUrl = (options as unknown as Record<symbol, unknown>)[BENCHMARK_URL];\n\n const totalBenchmarks = this.#targets.reduce((acc, t) => acc + t.measures.length * this.#feeds.length, 0);\n const progressMap = new Map<string, number>();\n let completedBenchmarks = 0;\n let bar: Progress | null = null;\n\n if (progress && totalBenchmarks > 0) {\n bar = new Progress(' [:bar] :percent :current/:total :label', {\n total: totalBenchmarks * 100,\n width: 30,\n complete: '=',\n incomplete: ' ',\n });\n }\n\n const onProgress = progress\n ? (info: ProgressInfo) => {\n progressMap.set(info.id, info.progress);\n const totalProgress = (completedBenchmarks + [...progressMap.values()].reduce((a, b) => a + b, 0)) * 100;\n const label = info.id.length > 30 ? info.id.slice(0, 27) + '...' : info.id;\n bar?.update(totalProgress / (totalBenchmarks * 100), { label });\n }\n : undefined;\n\n const executor = createExecutor<unknown, TInput, R>({\n workers,\n warmupCycles,\n maxCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver,\n reportTypes,\n onProgress,\n progressInterval,\n [BENCHMARK_URL]: benchmarkUrl,\n } as Required<ExecutorOptions<R>>);\n\n const reports: TargetReport<R>[] = [];\n for (const target of this.#targets) {\n const targetReport: TargetReport<R> = { target: target.title, measures: [] };\n for (const measure of target.measures) {\n const measureReport: MeasureReport<R> = { measure: measure.title, feeds: [] };\n for (const feed of this.#feeds) {\n const id = `${target.title}/${measure.title}/${feed.title}`;\n const data = await feed.fn?.();\n executor\n .push<ExecutorReport<R>>({\n id,\n setup: target.setup,\n teardown: target.teardown,\n pre: measure.pre,\n run: measure.run,\n post: measure.post,\n data,\n })\n .then((data) => {\n progressMap.delete(id);\n completedBenchmarks++;\n measureReport.feeds.push({\n feed: feed.title,\n data,\n });\n });\n }\n targetReport.measures.push(measureReport);\n }\n reports.push(targetReport);\n }\n await executor.drain();\n executor.kill();\n\n if (bar) {\n bar.update(1, { label: 'done' });\n bar.terminate();\n }\n\n return reports;\n }\n}\n\nexport const printSimpleReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.group('\\n', report.target, measure);\n for (const { feed, data } of feeds) {\n const { count, heapUsedKB, dceWarning, error: benchError, ...metrics } = data as Record<string, unknown>;\n if (benchError) {\n console.log(feed, `\\x1b[31m[error: ${benchError}]\\x1b[0m`);\n continue;\n }\n const output = Object.entries(metrics)\n .map(([key, report]) => `${key}: ${(report as { toString(): string }).toString()}`)\n .join('; ');\n const extras: string[] = [];\n if (heapUsedKB) extras.push(`heap: ${heapUsedKB}KB`);\n if (dceWarning) extras.push('\\x1b[33m[DCE warning]\\x1b[0m');\n const extrasStr = extras.length > 0 ? ` (${extras.join(', ')})` : '';\n console.log(feed, output + extrasStr);\n }\n console.groupEnd();\n }\n }\n};\n\nexport const printTableReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log('\\n', report.target, measure);\n const table: Record<string, unknown> = {};\n for (const { feed, data } of feeds) {\n const { error: benchError } = data as Record<string, unknown>;\n if (benchError) {\n table[feed] = { error: benchError };\n } else {\n table[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n }\n console.table(table);\n }\n }\n};\n\nexport const printJSONReports = <R extends ReportTypeList>(reports: TargetReport<R>[], padding?: number) => {\n const output = {} as Record<string, Record<string, Record<string, string>>>;\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n const row = {} as Record<string, Record<string, string>>;\n for (const { feed, data } of feeds) {\n const { error: benchError } = data as Record<string, unknown>;\n if (benchError) {\n row[feed] = { error: String(benchError) };\n } else {\n row[feed] = Object.fromEntries(Object.entries(data).map(([key, report]) => [key, report.toString()]));\n }\n }\n output[`${report.target} ${measure}`] = row;\n }\n }\n console.log(JSON.stringify(output, null, padding));\n};\n\nexport const printMarkdownReports = <R extends ReportTypeList>(reports: TargetReport<R>[]) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n## ${report.target} - ${measure}\\n`);\n if (feeds.length === 0) continue;\n\n const firstValid = feeds.find((f) => !(f.data as Record<string, unknown>).error);\n if (!firstValid) {\n for (const { feed, data } of feeds) {\n console.log(`| ${feed} | error: ${(data as Record<string, unknown>).error} |`);\n }\n continue;\n }\n const keys = Object.keys(firstValid.data).filter((k) => k !== 'count' && k !== 'error');\n const header = ['Feed', ...keys].join(' | ');\n const separator = ['---', ...keys.map(() => '---')].join(' | ');\n\n console.log(`| ${header} |`);\n console.log(`| ${separator} |`);\n\n for (const { feed, data } of feeds) {\n if ((data as Record<string, unknown>).error) {\n console.log(`| ${feed} | error: ${(data as Record<string, unknown>).error} |`);\n continue;\n }\n const values = keys.map((k) => (data as Record<string, { toString(): string }>)[k]?.toString() ?? '-');\n console.log(`| ${[feed, ...values].join(' | ')} |`);\n }\n }\n }\n};\n\nexport const printHistogramReports = <R extends ReportTypeList>(reports: TargetReport<R>[], width = 40) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n${report.target} - ${measure}\\n`);\n\n const opsKey = 'ops';\n const values = feeds.map((f) => {\n const { error: benchError } = f.data as Record<string, unknown>;\n return {\n feed: f.feed,\n value: benchError ? 0 : ((f.data as Record<string, { valueOf(): number }>)[opsKey]?.valueOf() ?? 0),\n error: benchError as string | undefined,\n };\n });\n\n const maxValue = Math.max(...values.map((v) => v.value));\n const maxLabelLen = Math.max(...values.map((v) => v.feed.length));\n\n for (const { feed, value, error } of values) {\n const label = feed.padEnd(maxLabelLen);\n if (error) {\n console.log(` ${label} | \\x1b[31m[error: ${error}]\\x1b[0m`);\n continue;\n }\n const barLen = maxValue > 0 ? Math.round((value / maxValue) * width) : 0;\n const bar = '\\u2588'.repeat(barLen);\n const formatted = value.toLocaleString('en-US', { maximumFractionDigits: 2 });\n console.log(` ${label} | ${bar} ${formatted} ops/s`);\n }\n }\n }\n};\n\nexport interface BaselineData {\n version: number;\n timestamp: string;\n results: Record<string, Record<string, number>>;\n}\n\nexport const reportsToBaseline = <R extends ReportTypeList>(reports: TargetReport<R>[]): BaselineData => {\n const results: Record<string, Record<string, number>> = {};\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n for (const { feed, data } of feeds) {\n if ((data as Record<string, unknown>).error) continue;\n const key = `${report.target}/${measure}/${feed}`;\n results[key] = {};\n for (const [metric, value] of Object.entries(data)) {\n if (metric !== 'count' && typeof (value as { valueOf(): number }).valueOf === 'function') {\n results[key][metric] = (value as { valueOf(): number }).valueOf();\n }\n }\n }\n }\n }\n return {\n version: 1,\n timestamp: new Date().toISOString(),\n results,\n };\n};\n\nexport const printComparisonReports = <R extends ReportTypeList>(reports: TargetReport<R>[], baseline: BaselineData, threshold = 5) => {\n for (const report of reports) {\n for (const { measure, feeds } of report.measures) {\n console.log(`\\n${report.target} - ${measure}\\n`);\n\n for (const { feed, data } of feeds) {\n const key = `${report.target}/${measure}/${feed}`;\n const baselineData = baseline.results[key];\n\n console.log(` ${feed}:`);\n\n if ((data as Record<string, unknown>).error) {\n console.log(` \\x1b[31m[error: ${(data as Record<string, unknown>).error}]\\x1b[0m`);\n continue;\n }\n\n for (const [metric, value] of Object.entries(data)) {\n if (metric === 'count') continue;\n const current = (value as { valueOf(): number }).valueOf();\n const baselineValue = baselineData?.[metric];\n\n if (baselineValue !== undefined && baselineValue !== 0) {\n const change = ((current - baselineValue) / baselineValue) * 100;\n const isOps = metric === 'ops';\n const improved = isOps ? change > threshold : change < -threshold;\n const regressed = isOps ? change < -threshold : change > threshold;\n\n let indicator = ' ';\n if (improved) indicator = '\\x1b[32m+\\x1b[0m';\n else if (regressed) indicator = '\\x1b[31m!\\x1b[0m';\n\n const changeStr = change >= 0 ? `+${change.toFixed(1)}%` : `${change.toFixed(1)}%`;\n const coloredChange = regressed ? `\\x1b[31m${changeStr}\\x1b[0m` : improved ? `\\x1b[32m${changeStr}\\x1b[0m` : changeStr;\n\n console.log(` ${indicator} ${metric}: ${(value as { toString(): string }).toString()} (${coloredChange})`);\n } else {\n console.log(` * ${metric}: ${(value as { toString(): string }).toString()} (new)`);\n }\n }\n }\n }\n }\n\n console.log(`\\nBaseline from: ${baseline.timestamp}`);\n};\n"],"names":["cpus","Progress","createExecutor","DEFAULT_CYCLES","DEFAULT_WORKERS","Math","max","ceil","length","AsyncFunction","BENCHMARK_URL","Symbol","for","DEFAULT_REPORT_TYPES","MeasureContext","pre","post","title","run","Measure","ctx","fn","TargetContext","teardown","measures","setup","Target","measure","push","FeedContext","Benchmark","create","feed","self","target","execute","options","workers","warmupCycles","maxCycles","minCycles","absThreshold","relThreshold","gcObserver","reportTypes","progress","progressInterval","Error","benchmarkUrl","totalBenchmarks","reduce","acc","t","progressMap","Map","completedBenchmarks","bar","total","width","complete","incomplete","onProgress","info","set","id","totalProgress","values","a","b","label","slice","update","undefined","executor","reports","targetReport","measureReport","feeds","data","then","delete","drain","kill","terminate","printSimpleReports","report","console","group","count","heapUsedKB","dceWarning","error","benchError","metrics","log","output","Object","entries","map","key","toString","join","extras","extrasStr","groupEnd","printTableReports","table","fromEntries","printJSONReports","padding","row","String","JSON","stringify","printMarkdownReports","firstValid","find","f","keys","filter","k","header","separator","printHistogramReports","opsKey","value","valueOf","maxValue","v","maxLabelLen","padEnd","barLen","round","repeat","formatted","toLocaleString","maximumFractionDigits","reportsToBaseline","results","metric","version","timestamp","Date","toISOString","printComparisonReports","baseline","threshold","baselineData","current","baselineValue","change","isOps","improved","regressed","indicator","changeStr","toFixed","coloredChange"],"mappings":"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"}
|
package/build/reporter.cjs
CHANGED
|
@@ -114,6 +114,27 @@ class Report {
|
|
|
114
114
|
return `${smartFixed(display)} ${unit}${uncertainty}`;
|
|
115
115
|
}
|
|
116
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
|
+
};
|
|
117
138
|
const createReport = (durations, type)=>{
|
|
118
139
|
const n = durations.length;
|
|
119
140
|
if (n === 0) {
|
|
@@ -159,123 +180,69 @@ const createReport = (durations, type)=>{
|
|
|
159
180
|
}
|
|
160
181
|
case 'ops':
|
|
161
182
|
{
|
|
162
|
-
|
|
163
|
-
for (const duration of durations){
|
|
164
|
-
sum += duration;
|
|
165
|
-
}
|
|
166
|
-
const avgScaled = sum / BigInt(n);
|
|
183
|
+
const { mean: avgScaled, ssd, n: nBig } = computeStats(durations);
|
|
167
184
|
const nsPerSecScaled = 1_000_000_000n * _typescjs.DURATION_SCALE;
|
|
168
185
|
const raw = Number(nsPerSecScaled) / Number(avgScaled);
|
|
169
186
|
const extra = raw < 1 ? Math.ceil(-Math.log10(raw)) : 0;
|
|
170
187
|
const exp = raw > 100 ? 0 : 2 + extra;
|
|
171
188
|
const scale = 10n ** BigInt(exp);
|
|
172
189
|
const value = avgScaled > 0n ? nsPerSecScaled * scale / avgScaled : 0n;
|
|
173
|
-
|
|
174
|
-
|
|
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
|
+
}
|
|
175
197
|
return new Report(type, value, uncertainty, scale);
|
|
176
198
|
}
|
|
177
199
|
case 'mean':
|
|
178
200
|
{
|
|
179
|
-
|
|
180
|
-
for (const duration of durations){
|
|
181
|
-
sum += duration;
|
|
182
|
-
}
|
|
201
|
+
const { sum } = computeStats(durations);
|
|
183
202
|
const value = (0, _utilscjs.divs)(sum, BigInt(n), 1n);
|
|
184
203
|
return new Report(type, value, 0, _typescjs.DURATION_SCALE);
|
|
185
204
|
}
|
|
186
205
|
case 'variance':
|
|
187
206
|
{
|
|
188
207
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE * _typescjs.DURATION_SCALE);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
sum += duration;
|
|
192
|
-
}
|
|
193
|
-
const mean = sum / BigInt(n);
|
|
194
|
-
let sumSquaredDiff = 0n;
|
|
195
|
-
for (const duration of durations){
|
|
196
|
-
const diff = duration - mean;
|
|
197
|
-
sumSquaredDiff += diff * diff;
|
|
198
|
-
}
|
|
199
|
-
const variance = sumSquaredDiff / BigInt(n - 1);
|
|
208
|
+
const { ssd } = computeStats(durations);
|
|
209
|
+
const variance = ssd / BigInt(n - 1);
|
|
200
210
|
return new Report(type, variance, 0, _typescjs.DURATION_SCALE * _typescjs.DURATION_SCALE);
|
|
201
211
|
}
|
|
202
212
|
case 'sd':
|
|
203
213
|
{
|
|
204
214
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const mean = sum / BigInt(n);
|
|
210
|
-
let sumSquaredDiff = 0n;
|
|
211
|
-
for (const duration of durations){
|
|
212
|
-
const diff = duration - mean;
|
|
213
|
-
sumSquaredDiff += diff * diff;
|
|
214
|
-
}
|
|
215
|
-
const variance = Number(sumSquaredDiff) / (n - 1);
|
|
216
|
-
const sd = Math.sqrt(variance);
|
|
217
|
-
const sdScaled = BigInt(Math.round(sd));
|
|
218
|
-
return new Report(type, sdScaled, 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
219
|
}
|
|
220
220
|
case 'sem':
|
|
221
221
|
{
|
|
222
222
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const mean = sum / BigInt(n);
|
|
228
|
-
let sumSquaredDiff = 0n;
|
|
229
|
-
for (const duration of durations){
|
|
230
|
-
const diff = duration - mean;
|
|
231
|
-
sumSquaredDiff += diff * diff;
|
|
232
|
-
}
|
|
233
|
-
const variance = Number(sumSquaredDiff) / (n - 1);
|
|
234
|
-
const sd = Math.sqrt(variance);
|
|
235
|
-
const sem = sd / Math.sqrt(n);
|
|
236
|
-
const semScaled = BigInt(Math.round(sem));
|
|
237
|
-
return new Report(type, semScaled, 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);
|
|
238
227
|
}
|
|
239
228
|
case 'moe':
|
|
240
229
|
{
|
|
241
230
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
let sumSquaredDiff = 0n;
|
|
248
|
-
for (const duration of durations){
|
|
249
|
-
const diff = duration - mean;
|
|
250
|
-
sumSquaredDiff += diff * diff;
|
|
251
|
-
}
|
|
252
|
-
const variance = Number(sumSquaredDiff) / (n - 1);
|
|
253
|
-
const sd = Math.sqrt(variance);
|
|
254
|
-
const sem = sd / Math.sqrt(n);
|
|
255
|
-
const moe = _typescjs.Z95 * sem;
|
|
256
|
-
const moeScaled = BigInt(Math.round(moe));
|
|
257
|
-
return new Report(type, moeScaled, 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);
|
|
258
236
|
}
|
|
259
237
|
case 'rme':
|
|
260
238
|
{
|
|
261
239
|
if (n < 2) return new Report(type, 0n);
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
let sumSquaredDiff = 0;
|
|
269
|
-
for (const duration of durations){
|
|
270
|
-
const diff = Number(duration) - mean;
|
|
271
|
-
sumSquaredDiff += diff * diff;
|
|
272
|
-
}
|
|
273
|
-
const variance = sumSquaredDiff / (n - 1);
|
|
274
|
-
const sd = Math.sqrt(variance);
|
|
275
|
-
const sem = sd / Math.sqrt(n);
|
|
276
|
-
const moe = _typescjs.Z95 * sem;
|
|
277
|
-
const rme = moe / mean * 100;
|
|
278
|
-
const rmeScaled = BigInt(Math.round(rme * 100));
|
|
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;
|
|
279
246
|
return new Report(type, rmeScaled, 0, 100n);
|
|
280
247
|
}
|
|
281
248
|
case 'mad':
|
|
@@ -304,42 +271,22 @@ const createReport = (durations, type)=>{
|
|
|
304
271
|
case 'ci_lower':
|
|
305
272
|
{
|
|
306
273
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
for (const duration of durations){
|
|
314
|
-
const diff = Number(duration) - mean;
|
|
315
|
-
sumSquaredDiff += diff * diff;
|
|
316
|
-
}
|
|
317
|
-
const variance = sumSquaredDiff / (n - 1);
|
|
318
|
-
const sd = Math.sqrt(variance);
|
|
319
|
-
const sem = sd / Math.sqrt(n);
|
|
320
|
-
const moe = _typescjs.Z95 * sem;
|
|
321
|
-
const ciLower = Math.max(0, mean - moe);
|
|
322
|
-
return new Report(type, BigInt(Math.round(ciLower)), 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);
|
|
323
280
|
}
|
|
324
281
|
case 'ci_upper':
|
|
325
282
|
{
|
|
326
283
|
if (n < 2) return new Report(type, 0n, 0, _typescjs.DURATION_SCALE);
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
for (const duration of durations){
|
|
334
|
-
const diff = Number(duration) - mean;
|
|
335
|
-
sumSquaredDiff += diff * diff;
|
|
336
|
-
}
|
|
337
|
-
const variance = sumSquaredDiff / (n - 1);
|
|
338
|
-
const sd = Math.sqrt(variance);
|
|
339
|
-
const sem = sd / Math.sqrt(n);
|
|
340
|
-
const moe = _typescjs.Z95 * sem;
|
|
341
|
-
const ciUpper = mean + moe;
|
|
342
|
-
return new Report(type, BigInt(Math.round(ciUpper)), 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);
|
|
343
290
|
}
|
|
344
291
|
default:
|
|
345
292
|
{
|
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, DURATION_SCALE, Z95 } 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\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 case 'variance': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE * DURATION_SCALE);\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = sum / BigInt(n);\n let sumSquaredDiff = 0n;\n for (const duration of durations) {\n const diff = duration - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = sumSquaredDiff / 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 let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = sum / BigInt(n);\n let sumSquaredDiff = 0n;\n for (const duration of durations) {\n const diff = duration - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = Number(sumSquaredDiff) / (n - 1);\n const sd = Math.sqrt(variance);\n const sdScaled = BigInt(Math.round(sd));\n return new Report(type, sdScaled, 0, DURATION_SCALE);\n }\n\n case 'sem': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = sum / BigInt(n);\n let sumSquaredDiff = 0n;\n for (const duration of durations) {\n const diff = duration - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = Number(sumSquaredDiff) / (n - 1);\n const sd = Math.sqrt(variance);\n const sem = sd / Math.sqrt(n);\n const semScaled = BigInt(Math.round(sem));\n return new Report(type, semScaled, 0, DURATION_SCALE);\n }\n\n case 'moe': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = sum / BigInt(n);\n let sumSquaredDiff = 0n;\n for (const duration of durations) {\n const diff = duration - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = Number(sumSquaredDiff) / (n - 1);\n const sd = Math.sqrt(variance);\n const sem = sd / Math.sqrt(n);\n const moe = Z95 * sem;\n const moeScaled = BigInt(Math.round(moe));\n return new Report(type, moeScaled, 0, DURATION_SCALE);\n }\n\n case 'rme': {\n if (n < 2) return new Report(type, 0n);\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = Number(sum) / n;\n if (mean === 0) return new Report(type, 0n);\n let sumSquaredDiff = 0;\n for (const duration of durations) {\n const diff = Number(duration) - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = sumSquaredDiff / (n - 1);\n const sd = Math.sqrt(variance);\n const sem = sd / Math.sqrt(n);\n const moe = Z95 * sem;\n const rme = (moe / mean) * 100;\n const rmeScaled = BigInt(Math.round(rme * 100));\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 let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = Number(sum) / n;\n let sumSquaredDiff = 0;\n for (const duration of durations) {\n const diff = Number(duration) - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = sumSquaredDiff / (n - 1);\n const sd = Math.sqrt(variance);\n const sem = sd / Math.sqrt(n);\n const moe = Z95 * sem;\n const ciLower = Math.max(0, mean - moe);\n return new Report(type, BigInt(Math.round(ciLower)), 0, DURATION_SCALE);\n }\n\n case 'ci_upper': {\n if (n < 2) return new Report(type, 0n, 0, DURATION_SCALE);\n let sum = 0n;\n for (const duration of durations) {\n sum += duration;\n }\n const mean = Number(sum) / n;\n let sumSquaredDiff = 0;\n for (const duration of durations) {\n const diff = Number(duration) - mean;\n sumSquaredDiff += diff * diff;\n }\n const variance = sumSquaredDiff / (n - 1);\n const sd = Math.sqrt(variance);\n const sem = sd / Math.sqrt(n);\n const moe = Z95 * sem;\n const ciUpper = mean + moe;\n return new Report(type, BigInt(Math.round(ciUpper)), 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","varianceUnits","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","mean","sumSquaredDiff","diff","variance","sd","sqrt","sdScaled","round","sem","semScaled","moe","Z95","moeScaled","rme","rmeScaled","medianIdx","median","deviations","BigUint64Array","i","sort","madIdx","mad","q1Idx","q3Idx","q1","q3","iqr","ciLower","ciUpper","p","slice","idx","min","prev","next"],"mappings":"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"}
|
|
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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"}
|