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/runner.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Control, DURATION_SCALE } from "./types.js";
|
|
|
3
3
|
import { GCWatcher } from "./gc-watcher.js";
|
|
4
4
|
const COMPLETE_VALUE = 100_00;
|
|
5
5
|
const hr = process.hrtime.bigint.bind(process.hrtime);
|
|
6
|
-
const sink = new Int32Array(
|
|
6
|
+
const sink = new Int32Array(1);
|
|
7
7
|
const consume = (value)=>{
|
|
8
8
|
let payload = 0;
|
|
9
9
|
switch(typeof value){
|
|
@@ -28,7 +28,7 @@ const consume = (value)=>{
|
|
|
28
28
|
default:
|
|
29
29
|
payload = -1;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
sink[0] ^= payload;
|
|
32
32
|
};
|
|
33
33
|
const runSync = (run, overhead)=>{
|
|
34
34
|
return (...args)=>{
|
|
@@ -404,12 +404,21 @@ export const benchmark = async ({ setup, teardown, pre, run: runRaw, post, data,
|
|
|
404
404
|
pushWindow(warmupWindow, Number(duration), warmupCap);
|
|
405
405
|
}
|
|
406
406
|
let i = 0;
|
|
407
|
-
|
|
408
|
-
let
|
|
407
|
+
const WELFORD_SCALE = 1_000_000n;
|
|
408
|
+
let meanS = 0n;
|
|
409
|
+
let m2S = 0n;
|
|
409
410
|
const outlierWindow = [];
|
|
410
411
|
let skipped = 0;
|
|
411
412
|
const maxSkipped = maxCycles * 10;
|
|
412
413
|
let disableFiltering = false;
|
|
414
|
+
const absThScaled = BigInt(Math.round(absThreshold)) * WELFORD_SCALE;
|
|
415
|
+
const absThSq = absThScaled * absThScaled;
|
|
416
|
+
const REL_PRECISION = 1_000_000n;
|
|
417
|
+
const relThBigint = BigInt(Math.round(relThreshold * Number(REL_PRECISION)));
|
|
418
|
+
const relThSq = relThBigint * relThBigint;
|
|
419
|
+
const relPrecSq = REL_PRECISION * REL_PRECISION;
|
|
420
|
+
const Z95_SQ_NUM = 38416n;
|
|
421
|
+
const Z95_SQ_DENOM = 10000n;
|
|
413
422
|
while(true){
|
|
414
423
|
if (i >= maxCycles) break;
|
|
415
424
|
if (!disableFiltering && skipped >= maxSkipped) {
|
|
@@ -461,39 +470,34 @@ export const benchmark = async ({ setup, teardown, pre, run: runRaw, post, data,
|
|
|
461
470
|
}
|
|
462
471
|
}
|
|
463
472
|
const durationNumber = Number(sampleDuration);
|
|
464
|
-
pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);
|
|
465
473
|
if (!disableFiltering) {
|
|
466
474
|
const { median, iqr } = medianAndIqr(outlierWindow);
|
|
475
|
+
pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);
|
|
467
476
|
const maxAllowed = median + OUTLIER_IQR_MULTIPLIER * iqr || Number.POSITIVE_INFINITY;
|
|
468
477
|
if (outlierWindow.length >= 8 && durationNumber > maxAllowed && durationNumber - median > OUTLIER_ABS_THRESHOLD) {
|
|
469
478
|
skipped++;
|
|
470
479
|
continue;
|
|
471
480
|
}
|
|
472
|
-
const meanNumber = Number(
|
|
481
|
+
const meanNumber = Number(meanS / WELFORD_SCALE);
|
|
473
482
|
if (i >= 8 && meanNumber > 0 && durationNumber > OUTLIER_MULTIPLIER * meanNumber && durationNumber - meanNumber > OUTLIER_ABS_THRESHOLD) {
|
|
474
483
|
skipped++;
|
|
475
484
|
continue;
|
|
476
485
|
}
|
|
486
|
+
} else {
|
|
487
|
+
pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);
|
|
477
488
|
}
|
|
478
489
|
durations[i++] = sampleDuration;
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
490
|
+
const deltaS = sampleDuration * WELFORD_SCALE - meanS;
|
|
491
|
+
meanS += deltaS / BigInt(i);
|
|
492
|
+
m2S += deltaS * (sampleDuration * WELFORD_SCALE - meanS);
|
|
482
493
|
const progress = i / maxCycles * COMPLETE_VALUE;
|
|
483
494
|
if (i % PROGRESS_STRIDE === 0) {
|
|
484
495
|
control[Control.PROGRESS] = progress;
|
|
485
496
|
}
|
|
486
497
|
if (i >= minCycles) {
|
|
487
|
-
|
|
488
|
-
const
|
|
489
|
-
if (
|
|
490
|
-
break;
|
|
491
|
-
}
|
|
492
|
-
const meanNum = Number(mean);
|
|
493
|
-
const cov = stddev / (meanNum || 1);
|
|
494
|
-
if (cov <= relThreshold) {
|
|
495
|
-
break;
|
|
496
|
-
}
|
|
498
|
+
if (m2S <= absThSq * BigInt(i - 1)) break;
|
|
499
|
+
const ni = BigInt(i);
|
|
500
|
+
if (meanS !== 0n && Z95_SQ_NUM * m2S * relPrecSq <= relThSq * ni * (ni - 1n) * meanS * meanS * Z95_SQ_DENOM) break;
|
|
497
501
|
}
|
|
498
502
|
}
|
|
499
503
|
control[Control.INDEX] = i;
|
package/build/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { performance, PerformanceObserver } from 'node:perf_hooks';\nimport { Options, Control, DURATION_SCALE } from './types.js';\nimport { GCWatcher } from './gc-watcher.js';\nimport { StepFn } from './types.js';\n\nconst COMPLETE_VALUE = 100_00;\n\nconst hr = process.hrtime.bigint.bind(process.hrtime);\n\nconst sink = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));\nconst consume = (value: unknown) => {\n let payload = 0;\n switch (typeof value) {\n case 'number':\n payload = Number.isFinite(value) ? Math.trunc(value) : 0;\n break;\n case 'bigint':\n payload = Number(value & 0xffff_ffffn);\n break;\n case 'string':\n payload = value.length;\n break;\n case 'boolean':\n payload = value ? 1 : 0;\n break;\n case 'object':\n payload = value === null ? 0 : 1;\n break;\n case 'function':\n payload = 1;\n break;\n default:\n payload = -1;\n }\n Atomics.xor(sink, 0, payload);\n};\n\nconst runSync = (run: Function, overhead: bigint) => {\n return (...args: unknown[]) => {\n const start = hr();\n const result = run(...args);\n consume(result);\n const duration = hr() - start;\n return duration > overhead ? duration - overhead : 0n;\n };\n};\n\nconst runAsync = (run: Function) => {\n return async (...args: unknown[]) => {\n const start = hr();\n const result = await run(...args);\n consume(result);\n return hr() - start;\n };\n};\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> => {\n return value !== null && (typeof value === 'object' || typeof value === 'function') && typeof (value as PromiseLike<unknown>).then === 'function';\n};\n\nconst TARGET_SAMPLE_NS = 1_000_000n; // aim for ~1ms per measured sample\nconst MAX_BATCH = 1_048_576;\nconst PROGRESS_STRIDE = 16;\nconst GC_STRIDE = 32;\nconst OUTLIER_MULTIPLIER = 4;\nconst OUTLIER_IQR_MULTIPLIER = 3;\nconst OUTLIER_WINDOW = 64;\nconst OUTLIER_ABS_THRESHOLD = 10_000_000;\nconst BASELINE_SAMPLES = 16;\nconst OUTLIER_SCRATCH = new Float64Array(OUTLIER_WINDOW);\n\ntype GCEvent = { start: number; end: number };\ntype RunTimedSync<TContext, TInput> = (ctx: TContext, data: TInput, nonce?: number) => bigint;\ntype RunTimedAsync<TContext, TInput> = (ctx: TContext, data: TInput, nonce?: number) => Promise<bigint>;\n\nconst measureTimerOverhead = () => {\n let total = 0n;\n for (let i = 0; i < BASELINE_SAMPLES; i++) {\n const start = hr();\n consume(0);\n total += hr() - start;\n }\n return total / BigInt(BASELINE_SAMPLES);\n};\n\nconst collectSample = async <TContext, TInput>({\n batchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n nextNonce,\n}: {\n batchSize: number;\n run: RunTimedSync<TContext, TInput> | RunTimedAsync<TContext, TInput>;\n runRaw: StepFn<TContext, TInput>;\n runIsAsync: boolean;\n pre: StepFn<TContext, TInput> | undefined;\n preIsAsync: boolean;\n post: StepFn<TContext, TInput> | undefined;\n postIsAsync: boolean;\n context: TContext;\n data: TInput;\n nextNonce: (() => number) | null;\n}) => {\n const canBatchTime = !runIsAsync && !pre && !post;\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, data, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, data));\n }\n }\n return ((hr() - batchStart) * DURATION_SCALE) / BigInt(batchSize);\n }\n\n let sampleDuration = 0n;\n for (let b = 0; b < batchSize; b++) {\n if (pre) {\n if (preIsAsync) {\n await pre(context, data);\n } else {\n pre(context, data);\n }\n }\n\n if (runIsAsync) {\n const runAsyncFn = run as RunTimedAsync<TContext, TInput>;\n const duration = nextNonce ? await runAsyncFn(context, data, nextNonce()) : await runAsyncFn(context, data);\n sampleDuration += duration;\n } else {\n const runSyncFn = run as RunTimedSync<TContext, TInput>;\n const duration = nextNonce ? runSyncFn(context, data, nextNonce()) : runSyncFn(context, data);\n sampleDuration += duration;\n }\n\n if (post) {\n if (postIsAsync) {\n await post(context, data);\n } else {\n post(context, data);\n }\n }\n }\n return (sampleDuration * DURATION_SCALE) / BigInt(batchSize);\n};\n\nconst tuneParameters = async <TContext, TInput>({\n initialBatch,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n minCycles,\n relThreshold,\n maxCycles,\n nextNonce,\n}: {\n initialBatch: number;\n run: RunTimedSync<TContext, TInput> | RunTimedAsync<TContext, TInput>;\n runRaw: StepFn<TContext, TInput>;\n runIsAsync: boolean;\n pre?: StepFn<TContext, TInput>;\n preIsAsync: boolean;\n post?: StepFn<TContext, TInput>;\n postIsAsync: boolean;\n context: TContext;\n data: TInput;\n minCycles: number;\n relThreshold: number;\n maxCycles: number;\n nextNonce: (() => number) | null;\n}) => {\n let batchSize = initialBatch;\n let bestCv = Number.POSITIVE_INFINITY;\n let bestBatch = batchSize;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const samples: number[] = [];\n const sampleCount = Math.min(8, maxCycles);\n for (let s = 0; s < sampleCount; s++) {\n const duration = await collectSample({\n batchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n nextNonce,\n });\n samples.push(Number(duration));\n }\n const mean = samples.reduce((acc, v) => acc + v, 0) / samples.length;\n const variance = samples.reduce((acc, v) => acc + (v - mean) * (v - mean), 0) / Math.max(1, samples.length - 1);\n const stddev = Math.sqrt(variance);\n const cv = mean === 0 ? Number.POSITIVE_INFINITY : stddev / mean;\n\n if (cv < bestCv) {\n bestCv = cv;\n bestBatch = batchSize;\n }\n\n if (cv <= relThreshold || batchSize >= MAX_BATCH) {\n break;\n }\n batchSize = Math.min(MAX_BATCH, batchSize * 2);\n }\n\n const tunedRel = bestCv < relThreshold ? Math.max(bestCv * 1.5, relThreshold * 0.5) : relThreshold;\n const tunedMin = Math.min(maxCycles, Math.max(minCycles, Math.ceil(minCycles * Math.max(1, bestCv / (relThreshold || 1e-6)))));\n\n return { batchSize: bestBatch, relThreshold: tunedRel, minCycles: tunedMin };\n};\n\nconst createGCTracker = () => {\n if (process.env.OVERTAKE_GC_OBSERVER !== '1') {\n return null;\n }\n if (typeof PerformanceObserver === 'undefined') {\n return null;\n }\n\n const events: GCEvent[] = [];\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n events.push({ start: entry.startTime, end: entry.startTime + entry.duration });\n }\n });\n\n try {\n observer.observe({ entryTypes: ['gc'] });\n } catch {\n return null;\n }\n\n const overlaps = (start: number, end: number) => {\n let noisy = false;\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.end < start - 5_000) {\n events.splice(i, 1);\n continue;\n }\n if (event.start <= end && event.end >= start) {\n noisy = true;\n }\n }\n return noisy;\n };\n\n const dispose = () => observer.disconnect();\n\n return { overlaps, dispose };\n};\n\nconst pushWindow = (arr: number[], value: number, cap: number) => {\n if (arr.length === cap) {\n arr.shift();\n }\n arr.push(value);\n};\n\nconst medianAndIqr = (arr: number[]) => {\n if (arr.length === 0) return { median: 0, iqr: 0 };\n for (let i = 0; i < arr.length; i++) {\n OUTLIER_SCRATCH[i] = arr[i];\n }\n const view = OUTLIER_SCRATCH.subarray(0, arr.length);\n view.sort();\n const mid = Math.floor(view.length / 2);\n const median = view.length % 2 === 0 ? (view[mid - 1] + view[mid]) / 2 : view[mid];\n const q1Idx = Math.floor(view.length * 0.25);\n const q3Idx = Math.floor(view.length * 0.75);\n const q1 = view[q1Idx];\n const q3 = view[q3Idx];\n return { median, iqr: q3 - q1 };\n};\n\nconst windowCv = (arr: number[]) => {\n if (arr.length < 2) return Number.POSITIVE_INFINITY;\n const mean = arr.reduce((a, v) => a + v, 0) / arr.length;\n const variance = arr.reduce((a, v) => a + (v - mean) * (v - mean), 0) / (arr.length - 1);\n const stddev = Math.sqrt(variance);\n return mean === 0 ? Number.POSITIVE_INFINITY : stddev / mean;\n};\n\nexport const benchmark = async <TContext, TInput>({\n setup,\n teardown,\n pre,\n run: runRaw,\n post,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver = false,\n\n durationsSAB,\n controlSAB,\n}: Required<Options<TContext, TInput>>) => {\n const durations = new BigUint64Array(durationsSAB);\n const control = new Int32Array(controlSAB);\n\n control[Control.INDEX] = 0;\n control[Control.PROGRESS] = 0;\n control[Control.COMPLETE] = 255;\n control[Control.HEAP_USED] = 0;\n\n const context = (await setup?.()) as TContext;\n const heapBefore = process.memoryUsage().heapUsed;\n const input = data as TInput;\n const maxCycles = durations.length;\n const gcWatcher = gcObserver ? new GCWatcher() : null;\n const gcTracker = gcObserver ? createGCTracker() : null;\n\n try {\n // classify sync/async and capture initial duration\n let preIsAsync = false;\n if (pre) {\n const preResult = pre(context, input);\n preIsAsync = isThenable(preResult);\n if (preIsAsync) {\n await preResult;\n }\n }\n\n const probeStart = hr();\n const probeResult = runRaw(context, input);\n const runIsAsync = isThenable(probeResult);\n if (runIsAsync) {\n const resolved = await probeResult;\n consume(resolved);\n } else {\n consume(probeResult);\n }\n const durationProbeRaw = hr() - probeStart;\n\n let postIsAsync = false;\n if (post) {\n const postResult = post(context, input);\n postIsAsync = isThenable(postResult);\n if (postIsAsync) {\n await postResult;\n }\n }\n\n const timerOverhead = runIsAsync ? 0n : measureTimerOverhead();\n let durationProbe = runIsAsync ? durationProbeRaw : durationProbeRaw > timerOverhead ? durationProbeRaw - timerOverhead : 0n;\n\n const shouldPerturbInput = process.env.OVERTAKE_PERTURB_INPUT === '1';\n let nonce = 0;\n const nextNonce = shouldPerturbInput\n ? () => {\n nonce = (nonce + 1) | 0;\n return nonce;\n }\n : null;\n\n if (!runIsAsync && !pre && !post) {\n const PROBE_TIME_LIMIT_NS = 1_000_000_000n;\n const INITIAL_PROBE_SIZE = 10;\n const MAX_PROBE_SIZE = 10_000;\n\n const initialStart = hr();\n if (nextNonce) {\n for (let i = 0; i < INITIAL_PROBE_SIZE; i++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let i = 0; i < INITIAL_PROBE_SIZE; i++) {\n consume(runRaw(context, input));\n }\n }\n const initialDuration = hr() - initialStart;\n const estimatedPerOp = initialDuration / BigInt(INITIAL_PROBE_SIZE);\n\n const remainingBudget = PROBE_TIME_LIMIT_NS - initialDuration;\n const additionalIterations = estimatedPerOp > 0n ? Number(remainingBudget / estimatedPerOp) : MAX_PROBE_SIZE - INITIAL_PROBE_SIZE;\n const cappedAdditional = Math.min(Math.max(0, additionalIterations), MAX_PROBE_SIZE - INITIAL_PROBE_SIZE);\n\n let totalIterations = INITIAL_PROBE_SIZE;\n if (cappedAdditional > 0) {\n if (nextNonce) {\n for (let i = 0; i < cappedAdditional; i++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let i = 0; i < cappedAdditional; i++) {\n consume(runRaw(context, input));\n }\n }\n totalIterations += cappedAdditional;\n }\n\n durationProbe = (hr() - initialStart) / BigInt(totalIterations);\n }\n\n const runTimedSync = runIsAsync ? null : runSync(runRaw, timerOverhead);\n const runTimedAsync = runIsAsync ? runAsync(runRaw) : null;\n const run = runIsAsync ? runTimedAsync! : runTimedSync!;\n\n const runOnceSync: RunTimedSync<TContext, TInput> | null = runIsAsync ? null : nextNonce ? (ctx, dataValue) => runTimedSync!(ctx, dataValue, nextNonce()) : runTimedSync!;\n const runOnceAsync: RunTimedAsync<TContext, TInput> | null = runIsAsync ? (nextNonce ? (ctx, dataValue) => runTimedAsync!(ctx, dataValue, nextNonce()) : runTimedAsync!) : null;\n\n const preSync = preIsAsync ? null : pre;\n const preAsync = preIsAsync ? pre : null;\n const postSync = postIsAsync ? null : post;\n const postAsync = postIsAsync ? post : null;\n\n // choose batch size to amortize timer overhead\n const durationPerRun = durationProbe === 0n ? 1n : durationProbe;\n const suggestedBatch = Number(TARGET_SAMPLE_NS / durationPerRun);\n const minBatchForFastOps = durationProbe < 100n ? 100_000 : 1;\n const initialBatchSize = Math.min(MAX_BATCH, Math.max(minBatchForFastOps, suggestedBatch));\n\n // auto-tune based on warmup samples\n const tuned = await tuneParameters({\n initialBatch: initialBatchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data: input,\n minCycles,\n relThreshold,\n maxCycles,\n nextNonce,\n });\n let batchSize = tuned.batchSize;\n minCycles = tuned.minCycles;\n relThreshold = tuned.relThreshold;\n\n // warmup: run until requested cycles, adapt if unstable\n const warmupStart = performance.now();\n let warmupRemaining = warmupCycles;\n const warmupWindow: number[] = [];\n const warmupCap = Math.max(warmupCycles, Math.min(maxCycles, warmupCycles * 4 || 1000));\n const canBatchTime = !runIsAsync && !preSync && !preAsync && !postSync && !postAsync;\n\n const runWarmup = async () => {\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, input));\n }\n }\n return ((hr() - batchStart) * DURATION_SCALE) / BigInt(batchSize);\n }\n\n if (preSync) {\n preSync(context, input);\n } else if (preAsync) {\n await preAsync(context, input);\n }\n\n const duration = runIsAsync ? await runOnceAsync!(context, input) : runOnceSync!(context, input);\n\n if (postSync) {\n postSync(context, input);\n } else if (postAsync) {\n await postAsync(context, input);\n }\n\n return duration * DURATION_SCALE;\n };\n\n while (performance.now() - warmupStart < 1_000 && warmupRemaining > 0) {\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n warmupRemaining--;\n }\n let warmupDone = 0;\n while (warmupDone < warmupRemaining) {\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n warmupDone++;\n if (global.gc && warmupDone % GC_STRIDE === 0) {\n global.gc();\n }\n }\n while (warmupWindow.length >= 8 && warmupWindow.length < warmupCap) {\n const cv = windowCv(warmupWindow);\n if (cv <= relThreshold * 2) {\n break;\n }\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n }\n\n let i = 0;\n let mean = 0n;\n let m2 = 0n;\n const outlierWindow: number[] = [];\n let skipped = 0;\n const maxSkipped = maxCycles * 10;\n let disableFiltering = false;\n\n while (true) {\n if (i >= maxCycles) break;\n if (!disableFiltering && skipped >= maxSkipped) {\n console.error(`Warning: ${skipped} samples skipped due to noise/outlier detection. ` + `Disabling filtering for remaining samples. Results may have higher variance.`);\n disableFiltering = true;\n }\n\n if (global.gc && i > 0 && i % GC_STRIDE === 0) {\n global.gc();\n }\n\n const gcMarker = gcWatcher?.start();\n const sampleStart = performance.now();\n let sampleDuration = 0n;\n\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, input));\n }\n }\n const batchDuration = hr() - batchStart;\n sampleDuration = (batchDuration * DURATION_SCALE) / BigInt(batchSize);\n } else {\n for (let b = 0; b < batchSize; b++) {\n if (preSync) {\n preSync(context, input);\n } else if (preAsync) {\n await preAsync(context, input);\n }\n\n const duration = runIsAsync ? await runOnceAsync!(context, input) : runOnceSync!(context, input);\n sampleDuration += duration;\n\n if (postSync) {\n postSync(context, input);\n } else if (postAsync) {\n await postAsync(context, input);\n }\n }\n sampleDuration = (sampleDuration * DURATION_SCALE) / BigInt(batchSize);\n }\n\n const sampleEnd = performance.now();\n if (!disableFiltering) {\n const gcNoise = (gcMarker ? gcWatcher!.seen(gcMarker) : false) || (gcTracker?.overlaps(sampleStart, sampleEnd) ?? false);\n if (gcNoise) {\n skipped++;\n continue;\n }\n }\n\n const durationNumber = Number(sampleDuration);\n pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);\n if (!disableFiltering) {\n const { median, iqr } = medianAndIqr(outlierWindow);\n const maxAllowed = median + OUTLIER_IQR_MULTIPLIER * iqr || Number.POSITIVE_INFINITY;\n if (outlierWindow.length >= 8 && durationNumber > maxAllowed && durationNumber - median > OUTLIER_ABS_THRESHOLD) {\n skipped++;\n continue;\n }\n\n const meanNumber = Number(mean);\n if (i >= 8 && meanNumber > 0 && durationNumber > OUTLIER_MULTIPLIER * meanNumber && durationNumber - meanNumber > OUTLIER_ABS_THRESHOLD) {\n skipped++;\n continue;\n }\n }\n\n durations[i++] = sampleDuration;\n const delta = sampleDuration - mean;\n mean += delta / BigInt(i);\n m2 += delta * (sampleDuration - mean);\n\n const progress = (i / maxCycles) * COMPLETE_VALUE;\n if (i % PROGRESS_STRIDE === 0) {\n control[Control.PROGRESS] = progress;\n }\n\n if (i >= minCycles) {\n const variance = Number(m2) / (i - 1);\n const stddev = Math.sqrt(variance);\n if (stddev <= Number(absThreshold)) {\n break;\n }\n\n const meanNum = Number(mean);\n const cov = stddev / (meanNum || 1);\n if (cov <= relThreshold) {\n break;\n }\n }\n }\n\n control[Control.INDEX] = i;\n control[Control.COMPLETE] = 0;\n const heapAfter = process.memoryUsage().heapUsed;\n control[Control.HEAP_USED] = Math.max(0, Math.round((heapAfter - heapBefore) / 1024));\n } catch (e) {\n console.error(e && typeof e === 'object' && 'stack' in e ? e.stack : e);\n control[Control.COMPLETE] = 1;\n } finally {\n gcTracker?.dispose?.();\n try {\n await teardown?.(context);\n } catch (e) {\n control[Control.COMPLETE] = 2;\n console.error(e && typeof e === 'object' && 'stack' in e ? e.stack : e);\n }\n }\n\n return control[Control.COMPLETE];\n};\n"],"names":["performance","PerformanceObserver","Control","DURATION_SCALE","GCWatcher","COMPLETE_VALUE","hr","process","hrtime","bigint","bind","sink","Int32Array","SharedArrayBuffer","BYTES_PER_ELEMENT","consume","value","payload","Number","isFinite","Math","trunc","length","Atomics","xor","runSync","run","overhead","args","start","result","duration","runAsync","isThenable","then","TARGET_SAMPLE_NS","MAX_BATCH","PROGRESS_STRIDE","GC_STRIDE","OUTLIER_MULTIPLIER","OUTLIER_IQR_MULTIPLIER","OUTLIER_WINDOW","OUTLIER_ABS_THRESHOLD","BASELINE_SAMPLES","OUTLIER_SCRATCH","Float64Array","measureTimerOverhead","total","i","BigInt","collectSample","batchSize","runRaw","runIsAsync","pre","preIsAsync","post","postIsAsync","context","data","nextNonce","canBatchTime","batchStart","b","sampleDuration","runAsyncFn","runSyncFn","tuneParameters","initialBatch","minCycles","relThreshold","maxCycles","bestCv","POSITIVE_INFINITY","bestBatch","attempt","samples","sampleCount","min","s","push","mean","reduce","acc","v","variance","max","stddev","sqrt","cv","tunedRel","tunedMin","ceil","createGCTracker","env","OVERTAKE_GC_OBSERVER","events","observer","list","entry","getEntries","startTime","end","observe","entryTypes","overlaps","noisy","event","splice","dispose","disconnect","pushWindow","arr","cap","shift","medianAndIqr","median","iqr","view","subarray","sort","mid","floor","q1Idx","q3Idx","q1","q3","windowCv","a","benchmark","setup","teardown","warmupCycles","absThreshold","gcObserver","durationsSAB","controlSAB","durations","BigUint64Array","control","INDEX","PROGRESS","COMPLETE","HEAP_USED","heapBefore","memoryUsage","heapUsed","input","gcWatcher","gcTracker","preResult","probeStart","probeResult","resolved","durationProbeRaw","postResult","timerOverhead","durationProbe","shouldPerturbInput","OVERTAKE_PERTURB_INPUT","nonce","PROBE_TIME_LIMIT_NS","INITIAL_PROBE_SIZE","MAX_PROBE_SIZE","initialStart","initialDuration","estimatedPerOp","remainingBudget","additionalIterations","cappedAdditional","totalIterations","runTimedSync","runTimedAsync","runOnceSync","ctx","dataValue","runOnceAsync","preSync","preAsync","postSync","postAsync","durationPerRun","suggestedBatch","minBatchForFastOps","initialBatchSize","tuned","warmupStart","now","warmupRemaining","warmupWindow","warmupCap","runWarmup","warmupDone","global","gc","m2","outlierWindow","skipped","maxSkipped","disableFiltering","console","error","gcMarker","sampleStart","batchDuration","sampleEnd","gcNoise","seen","durationNumber","maxAllowed","meanNumber","delta","progress","meanNum","cov","heapAfter","round","e","stack"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { performance, PerformanceObserver } from 'node:perf_hooks';\nimport { Options, Control, DURATION_SCALE } from './types.js';\nimport { GCWatcher } from './gc-watcher.js';\nimport { StepFn } from './types.js';\n\nconst COMPLETE_VALUE = 100_00;\n\nconst hr = process.hrtime.bigint.bind(process.hrtime);\n\nconst sink = new Int32Array(1);\nconst consume = (value: unknown) => {\n let payload = 0;\n switch (typeof value) {\n case 'number':\n payload = Number.isFinite(value) ? Math.trunc(value) : 0;\n break;\n case 'bigint':\n payload = Number(value & 0xffff_ffffn);\n break;\n case 'string':\n payload = value.length;\n break;\n case 'boolean':\n payload = value ? 1 : 0;\n break;\n case 'object':\n payload = value === null ? 0 : 1;\n break;\n case 'function':\n payload = 1;\n break;\n default:\n payload = -1;\n }\n sink[0] ^= payload;\n};\n\nconst runSync = (run: Function, overhead: bigint) => {\n return (...args: unknown[]) => {\n const start = hr();\n const result = run(...args);\n consume(result);\n const duration = hr() - start;\n return duration > overhead ? duration - overhead : 0n;\n };\n};\n\nconst runAsync = (run: Function) => {\n return async (...args: unknown[]) => {\n const start = hr();\n const result = await run(...args);\n consume(result);\n return hr() - start;\n };\n};\n\nconst isThenable = (value: unknown): value is PromiseLike<unknown> => {\n return value !== null && (typeof value === 'object' || typeof value === 'function') && typeof (value as PromiseLike<unknown>).then === 'function';\n};\n\nconst TARGET_SAMPLE_NS = 1_000_000n; // aim for ~1ms per measured sample\nconst MAX_BATCH = 1_048_576;\nconst PROGRESS_STRIDE = 16;\nconst GC_STRIDE = 32;\nconst OUTLIER_MULTIPLIER = 4;\nconst OUTLIER_IQR_MULTIPLIER = 3;\nconst OUTLIER_WINDOW = 64;\nconst OUTLIER_ABS_THRESHOLD = 10_000_000;\nconst BASELINE_SAMPLES = 16;\nconst OUTLIER_SCRATCH = new Float64Array(OUTLIER_WINDOW);\n\ntype GCEvent = { start: number; end: number };\ntype RunTimedSync<TContext, TInput> = (ctx: TContext, data: TInput, nonce?: number) => bigint;\ntype RunTimedAsync<TContext, TInput> = (ctx: TContext, data: TInput, nonce?: number) => Promise<bigint>;\n\nconst measureTimerOverhead = () => {\n let total = 0n;\n for (let i = 0; i < BASELINE_SAMPLES; i++) {\n const start = hr();\n consume(0);\n total += hr() - start;\n }\n return total / BigInt(BASELINE_SAMPLES);\n};\n\nconst collectSample = async <TContext, TInput>({\n batchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n nextNonce,\n}: {\n batchSize: number;\n run: RunTimedSync<TContext, TInput> | RunTimedAsync<TContext, TInput>;\n runRaw: StepFn<TContext, TInput>;\n runIsAsync: boolean;\n pre: StepFn<TContext, TInput> | undefined;\n preIsAsync: boolean;\n post: StepFn<TContext, TInput> | undefined;\n postIsAsync: boolean;\n context: TContext;\n data: TInput;\n nextNonce: (() => number) | null;\n}) => {\n const canBatchTime = !runIsAsync && !pre && !post;\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, data, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, data));\n }\n }\n return ((hr() - batchStart) * DURATION_SCALE) / BigInt(batchSize);\n }\n\n let sampleDuration = 0n;\n for (let b = 0; b < batchSize; b++) {\n if (pre) {\n if (preIsAsync) {\n await pre(context, data);\n } else {\n pre(context, data);\n }\n }\n\n if (runIsAsync) {\n const runAsyncFn = run as RunTimedAsync<TContext, TInput>;\n const duration = nextNonce ? await runAsyncFn(context, data, nextNonce()) : await runAsyncFn(context, data);\n sampleDuration += duration;\n } else {\n const runSyncFn = run as RunTimedSync<TContext, TInput>;\n const duration = nextNonce ? runSyncFn(context, data, nextNonce()) : runSyncFn(context, data);\n sampleDuration += duration;\n }\n\n if (post) {\n if (postIsAsync) {\n await post(context, data);\n } else {\n post(context, data);\n }\n }\n }\n return (sampleDuration * DURATION_SCALE) / BigInt(batchSize);\n};\n\nconst tuneParameters = async <TContext, TInput>({\n initialBatch,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n minCycles,\n relThreshold,\n maxCycles,\n nextNonce,\n}: {\n initialBatch: number;\n run: RunTimedSync<TContext, TInput> | RunTimedAsync<TContext, TInput>;\n runRaw: StepFn<TContext, TInput>;\n runIsAsync: boolean;\n pre?: StepFn<TContext, TInput>;\n preIsAsync: boolean;\n post?: StepFn<TContext, TInput>;\n postIsAsync: boolean;\n context: TContext;\n data: TInput;\n minCycles: number;\n relThreshold: number;\n maxCycles: number;\n nextNonce: (() => number) | null;\n}) => {\n let batchSize = initialBatch;\n let bestCv = Number.POSITIVE_INFINITY;\n let bestBatch = batchSize;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const samples: number[] = [];\n const sampleCount = Math.min(8, maxCycles);\n for (let s = 0; s < sampleCount; s++) {\n const duration = await collectSample({\n batchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data,\n nextNonce,\n });\n samples.push(Number(duration));\n }\n const mean = samples.reduce((acc, v) => acc + v, 0) / samples.length;\n const variance = samples.reduce((acc, v) => acc + (v - mean) * (v - mean), 0) / Math.max(1, samples.length - 1);\n const stddev = Math.sqrt(variance);\n const cv = mean === 0 ? Number.POSITIVE_INFINITY : stddev / mean;\n\n if (cv < bestCv) {\n bestCv = cv;\n bestBatch = batchSize;\n }\n\n if (cv <= relThreshold || batchSize >= MAX_BATCH) {\n break;\n }\n batchSize = Math.min(MAX_BATCH, batchSize * 2);\n }\n\n const tunedRel = bestCv < relThreshold ? Math.max(bestCv * 1.5, relThreshold * 0.5) : relThreshold;\n const tunedMin = Math.min(maxCycles, Math.max(minCycles, Math.ceil(minCycles * Math.max(1, bestCv / (relThreshold || 1e-6)))));\n\n return { batchSize: bestBatch, relThreshold: tunedRel, minCycles: tunedMin };\n};\n\nconst createGCTracker = () => {\n if (process.env.OVERTAKE_GC_OBSERVER !== '1') {\n return null;\n }\n if (typeof PerformanceObserver === 'undefined') {\n return null;\n }\n\n const events: GCEvent[] = [];\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n events.push({ start: entry.startTime, end: entry.startTime + entry.duration });\n }\n });\n\n try {\n observer.observe({ entryTypes: ['gc'] });\n } catch {\n return null;\n }\n\n const overlaps = (start: number, end: number) => {\n let noisy = false;\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.end < start - 5_000) {\n events.splice(i, 1);\n continue;\n }\n if (event.start <= end && event.end >= start) {\n noisy = true;\n }\n }\n return noisy;\n };\n\n const dispose = () => observer.disconnect();\n\n return { overlaps, dispose };\n};\n\nconst pushWindow = (arr: number[], value: number, cap: number) => {\n if (arr.length === cap) {\n arr.shift();\n }\n arr.push(value);\n};\n\nconst medianAndIqr = (arr: number[]) => {\n if (arr.length === 0) return { median: 0, iqr: 0 };\n for (let i = 0; i < arr.length; i++) {\n OUTLIER_SCRATCH[i] = arr[i];\n }\n const view = OUTLIER_SCRATCH.subarray(0, arr.length);\n view.sort();\n const mid = Math.floor(view.length / 2);\n const median = view.length % 2 === 0 ? (view[mid - 1] + view[mid]) / 2 : view[mid];\n const q1Idx = Math.floor(view.length * 0.25);\n const q3Idx = Math.floor(view.length * 0.75);\n const q1 = view[q1Idx];\n const q3 = view[q3Idx];\n return { median, iqr: q3 - q1 };\n};\n\nconst windowCv = (arr: number[]) => {\n if (arr.length < 2) return Number.POSITIVE_INFINITY;\n const mean = arr.reduce((a, v) => a + v, 0) / arr.length;\n const variance = arr.reduce((a, v) => a + (v - mean) * (v - mean), 0) / (arr.length - 1);\n const stddev = Math.sqrt(variance);\n return mean === 0 ? Number.POSITIVE_INFINITY : stddev / mean;\n};\n\nexport const benchmark = async <TContext, TInput>({\n setup,\n teardown,\n pre,\n run: runRaw,\n post,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver = false,\n\n durationsSAB,\n controlSAB,\n}: Required<Options<TContext, TInput>>) => {\n const durations = new BigUint64Array(durationsSAB);\n const control = new Int32Array(controlSAB);\n\n control[Control.INDEX] = 0;\n control[Control.PROGRESS] = 0;\n control[Control.COMPLETE] = 255;\n control[Control.HEAP_USED] = 0;\n\n const context = (await setup?.()) as TContext;\n const heapBefore = process.memoryUsage().heapUsed;\n const input = data as TInput;\n const maxCycles = durations.length;\n const gcWatcher = gcObserver ? new GCWatcher() : null;\n const gcTracker = gcObserver ? createGCTracker() : null;\n\n try {\n // classify sync/async and capture initial duration\n let preIsAsync = false;\n if (pre) {\n const preResult = pre(context, input);\n preIsAsync = isThenable(preResult);\n if (preIsAsync) {\n await preResult;\n }\n }\n\n const probeStart = hr();\n const probeResult = runRaw(context, input);\n const runIsAsync = isThenable(probeResult);\n if (runIsAsync) {\n const resolved = await probeResult;\n consume(resolved);\n } else {\n consume(probeResult);\n }\n const durationProbeRaw = hr() - probeStart;\n\n let postIsAsync = false;\n if (post) {\n const postResult = post(context, input);\n postIsAsync = isThenable(postResult);\n if (postIsAsync) {\n await postResult;\n }\n }\n\n const timerOverhead = runIsAsync ? 0n : measureTimerOverhead();\n let durationProbe = runIsAsync ? durationProbeRaw : durationProbeRaw > timerOverhead ? durationProbeRaw - timerOverhead : 0n;\n\n const shouldPerturbInput = process.env.OVERTAKE_PERTURB_INPUT === '1';\n let nonce = 0;\n const nextNonce = shouldPerturbInput\n ? () => {\n nonce = (nonce + 1) | 0;\n return nonce;\n }\n : null;\n\n if (!runIsAsync && !pre && !post) {\n const PROBE_TIME_LIMIT_NS = 1_000_000_000n;\n const INITIAL_PROBE_SIZE = 10;\n const MAX_PROBE_SIZE = 10_000;\n\n const initialStart = hr();\n if (nextNonce) {\n for (let i = 0; i < INITIAL_PROBE_SIZE; i++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let i = 0; i < INITIAL_PROBE_SIZE; i++) {\n consume(runRaw(context, input));\n }\n }\n const initialDuration = hr() - initialStart;\n const estimatedPerOp = initialDuration / BigInt(INITIAL_PROBE_SIZE);\n\n const remainingBudget = PROBE_TIME_LIMIT_NS - initialDuration;\n const additionalIterations = estimatedPerOp > 0n ? Number(remainingBudget / estimatedPerOp) : MAX_PROBE_SIZE - INITIAL_PROBE_SIZE;\n const cappedAdditional = Math.min(Math.max(0, additionalIterations), MAX_PROBE_SIZE - INITIAL_PROBE_SIZE);\n\n let totalIterations = INITIAL_PROBE_SIZE;\n if (cappedAdditional > 0) {\n if (nextNonce) {\n for (let i = 0; i < cappedAdditional; i++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let i = 0; i < cappedAdditional; i++) {\n consume(runRaw(context, input));\n }\n }\n totalIterations += cappedAdditional;\n }\n\n durationProbe = (hr() - initialStart) / BigInt(totalIterations);\n }\n\n const runTimedSync = runIsAsync ? null : runSync(runRaw, timerOverhead);\n const runTimedAsync = runIsAsync ? runAsync(runRaw) : null;\n const run = runIsAsync ? runTimedAsync! : runTimedSync!;\n\n const runOnceSync: RunTimedSync<TContext, TInput> | null = runIsAsync ? null : nextNonce ? (ctx, dataValue) => runTimedSync!(ctx, dataValue, nextNonce()) : runTimedSync!;\n const runOnceAsync: RunTimedAsync<TContext, TInput> | null = runIsAsync ? (nextNonce ? (ctx, dataValue) => runTimedAsync!(ctx, dataValue, nextNonce()) : runTimedAsync!) : null;\n\n const preSync = preIsAsync ? null : pre;\n const preAsync = preIsAsync ? pre : null;\n const postSync = postIsAsync ? null : post;\n const postAsync = postIsAsync ? post : null;\n\n // choose batch size to amortize timer overhead\n const durationPerRun = durationProbe === 0n ? 1n : durationProbe;\n const suggestedBatch = Number(TARGET_SAMPLE_NS / durationPerRun);\n const minBatchForFastOps = durationProbe < 100n ? 100_000 : 1;\n const initialBatchSize = Math.min(MAX_BATCH, Math.max(minBatchForFastOps, suggestedBatch));\n\n // auto-tune based on warmup samples\n const tuned = await tuneParameters({\n initialBatch: initialBatchSize,\n run,\n runRaw,\n runIsAsync,\n pre,\n preIsAsync,\n post,\n postIsAsync,\n context,\n data: input,\n minCycles,\n relThreshold,\n maxCycles,\n nextNonce,\n });\n let batchSize = tuned.batchSize;\n minCycles = tuned.minCycles;\n relThreshold = tuned.relThreshold;\n\n // warmup: run until requested cycles, adapt if unstable\n const warmupStart = performance.now();\n let warmupRemaining = warmupCycles;\n const warmupWindow: number[] = [];\n const warmupCap = Math.max(warmupCycles, Math.min(maxCycles, warmupCycles * 4 || 1000));\n const canBatchTime = !runIsAsync && !preSync && !preAsync && !postSync && !postAsync;\n\n const runWarmup = async () => {\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, input));\n }\n }\n return ((hr() - batchStart) * DURATION_SCALE) / BigInt(batchSize);\n }\n\n if (preSync) {\n preSync(context, input);\n } else if (preAsync) {\n await preAsync(context, input);\n }\n\n const duration = runIsAsync ? await runOnceAsync!(context, input) : runOnceSync!(context, input);\n\n if (postSync) {\n postSync(context, input);\n } else if (postAsync) {\n await postAsync(context, input);\n }\n\n return duration * DURATION_SCALE;\n };\n\n while (performance.now() - warmupStart < 1_000 && warmupRemaining > 0) {\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n warmupRemaining--;\n }\n let warmupDone = 0;\n while (warmupDone < warmupRemaining) {\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n warmupDone++;\n if (global.gc && warmupDone % GC_STRIDE === 0) {\n global.gc();\n }\n }\n while (warmupWindow.length >= 8 && warmupWindow.length < warmupCap) {\n const cv = windowCv(warmupWindow);\n if (cv <= relThreshold * 2) {\n break;\n }\n const duration = await runWarmup();\n pushWindow(warmupWindow, Number(duration), warmupCap);\n }\n\n let i = 0;\n const WELFORD_SCALE = 1_000_000n;\n let meanS = 0n;\n let m2S = 0n;\n const outlierWindow: number[] = [];\n let skipped = 0;\n const maxSkipped = maxCycles * 10;\n let disableFiltering = false;\n\n const absThScaled = BigInt(Math.round(absThreshold)) * WELFORD_SCALE;\n const absThSq = absThScaled * absThScaled;\n const REL_PRECISION = 1_000_000n;\n const relThBigint = BigInt(Math.round(relThreshold * Number(REL_PRECISION)));\n const relThSq = relThBigint * relThBigint;\n const relPrecSq = REL_PRECISION * REL_PRECISION;\n const Z95_SQ_NUM = 38416n;\n const Z95_SQ_DENOM = 10000n;\n\n while (true) {\n if (i >= maxCycles) break;\n if (!disableFiltering && skipped >= maxSkipped) {\n console.error(`Warning: ${skipped} samples skipped due to noise/outlier detection. ` + `Disabling filtering for remaining samples. Results may have higher variance.`);\n disableFiltering = true;\n }\n\n if (global.gc && i > 0 && i % GC_STRIDE === 0) {\n global.gc();\n }\n\n const gcMarker = gcWatcher?.start();\n const sampleStart = performance.now();\n let sampleDuration = 0n;\n\n if (canBatchTime) {\n const batchStart = hr();\n if (nextNonce) {\n for (let b = 0; b < batchSize; b++) {\n consume((runRaw as Function)(context, input, nextNonce()));\n }\n } else {\n for (let b = 0; b < batchSize; b++) {\n consume(runRaw(context, input));\n }\n }\n const batchDuration = hr() - batchStart;\n sampleDuration = (batchDuration * DURATION_SCALE) / BigInt(batchSize);\n } else {\n for (let b = 0; b < batchSize; b++) {\n if (preSync) {\n preSync(context, input);\n } else if (preAsync) {\n await preAsync(context, input);\n }\n\n const duration = runIsAsync ? await runOnceAsync!(context, input) : runOnceSync!(context, input);\n sampleDuration += duration;\n\n if (postSync) {\n postSync(context, input);\n } else if (postAsync) {\n await postAsync(context, input);\n }\n }\n sampleDuration = (sampleDuration * DURATION_SCALE) / BigInt(batchSize);\n }\n\n const sampleEnd = performance.now();\n if (!disableFiltering) {\n const gcNoise = (gcMarker ? gcWatcher!.seen(gcMarker) : false) || (gcTracker?.overlaps(sampleStart, sampleEnd) ?? false);\n if (gcNoise) {\n skipped++;\n continue;\n }\n }\n\n const durationNumber = Number(sampleDuration);\n if (!disableFiltering) {\n const { median, iqr } = medianAndIqr(outlierWindow);\n pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);\n const maxAllowed = median + OUTLIER_IQR_MULTIPLIER * iqr || Number.POSITIVE_INFINITY;\n if (outlierWindow.length >= 8 && durationNumber > maxAllowed && durationNumber - median > OUTLIER_ABS_THRESHOLD) {\n skipped++;\n continue;\n }\n\n const meanNumber = Number(meanS / WELFORD_SCALE);\n if (i >= 8 && meanNumber > 0 && durationNumber > OUTLIER_MULTIPLIER * meanNumber && durationNumber - meanNumber > OUTLIER_ABS_THRESHOLD) {\n skipped++;\n continue;\n }\n } else {\n pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);\n }\n\n durations[i++] = sampleDuration;\n const deltaS = sampleDuration * WELFORD_SCALE - meanS;\n meanS += deltaS / BigInt(i);\n m2S += deltaS * (sampleDuration * WELFORD_SCALE - meanS);\n\n const progress = (i / maxCycles) * COMPLETE_VALUE;\n if (i % PROGRESS_STRIDE === 0) {\n control[Control.PROGRESS] = progress;\n }\n\n if (i >= minCycles) {\n if (m2S <= absThSq * BigInt(i - 1)) break;\n // RME convergence: Z95 * sem/mean <= relThreshold\n // Z95^2 * m2S / (n*(n-1)*meanS^2) <= relThreshold^2\n const ni = BigInt(i);\n if (meanS !== 0n && Z95_SQ_NUM * m2S * relPrecSq <= relThSq * ni * (ni - 1n) * meanS * meanS * Z95_SQ_DENOM) break;\n }\n }\n\n control[Control.INDEX] = i;\n control[Control.COMPLETE] = 0;\n const heapAfter = process.memoryUsage().heapUsed;\n control[Control.HEAP_USED] = Math.max(0, Math.round((heapAfter - heapBefore) / 1024));\n } catch (e) {\n console.error(e && typeof e === 'object' && 'stack' in e ? e.stack : e);\n control[Control.COMPLETE] = 1;\n } finally {\n gcTracker?.dispose?.();\n try {\n await teardown?.(context);\n } catch (e) {\n control[Control.COMPLETE] = 2;\n console.error(e && typeof e === 'object' && 'stack' in e ? e.stack : e);\n }\n }\n\n return control[Control.COMPLETE];\n};\n"],"names":["performance","PerformanceObserver","Control","DURATION_SCALE","GCWatcher","COMPLETE_VALUE","hr","process","hrtime","bigint","bind","sink","Int32Array","consume","value","payload","Number","isFinite","Math","trunc","length","runSync","run","overhead","args","start","result","duration","runAsync","isThenable","then","TARGET_SAMPLE_NS","MAX_BATCH","PROGRESS_STRIDE","GC_STRIDE","OUTLIER_MULTIPLIER","OUTLIER_IQR_MULTIPLIER","OUTLIER_WINDOW","OUTLIER_ABS_THRESHOLD","BASELINE_SAMPLES","OUTLIER_SCRATCH","Float64Array","measureTimerOverhead","total","i","BigInt","collectSample","batchSize","runRaw","runIsAsync","pre","preIsAsync","post","postIsAsync","context","data","nextNonce","canBatchTime","batchStart","b","sampleDuration","runAsyncFn","runSyncFn","tuneParameters","initialBatch","minCycles","relThreshold","maxCycles","bestCv","POSITIVE_INFINITY","bestBatch","attempt","samples","sampleCount","min","s","push","mean","reduce","acc","v","variance","max","stddev","sqrt","cv","tunedRel","tunedMin","ceil","createGCTracker","env","OVERTAKE_GC_OBSERVER","events","observer","list","entry","getEntries","startTime","end","observe","entryTypes","overlaps","noisy","event","splice","dispose","disconnect","pushWindow","arr","cap","shift","medianAndIqr","median","iqr","view","subarray","sort","mid","floor","q1Idx","q3Idx","q1","q3","windowCv","a","benchmark","setup","teardown","warmupCycles","absThreshold","gcObserver","durationsSAB","controlSAB","durations","BigUint64Array","control","INDEX","PROGRESS","COMPLETE","HEAP_USED","heapBefore","memoryUsage","heapUsed","input","gcWatcher","gcTracker","preResult","probeStart","probeResult","resolved","durationProbeRaw","postResult","timerOverhead","durationProbe","shouldPerturbInput","OVERTAKE_PERTURB_INPUT","nonce","PROBE_TIME_LIMIT_NS","INITIAL_PROBE_SIZE","MAX_PROBE_SIZE","initialStart","initialDuration","estimatedPerOp","remainingBudget","additionalIterations","cappedAdditional","totalIterations","runTimedSync","runTimedAsync","runOnceSync","ctx","dataValue","runOnceAsync","preSync","preAsync","postSync","postAsync","durationPerRun","suggestedBatch","minBatchForFastOps","initialBatchSize","tuned","warmupStart","now","warmupRemaining","warmupWindow","warmupCap","runWarmup","warmupDone","global","gc","WELFORD_SCALE","meanS","m2S","outlierWindow","skipped","maxSkipped","disableFiltering","absThScaled","round","absThSq","REL_PRECISION","relThBigint","relThSq","relPrecSq","Z95_SQ_NUM","Z95_SQ_DENOM","console","error","gcMarker","sampleStart","batchDuration","sampleEnd","gcNoise","seen","durationNumber","maxAllowed","meanNumber","deltaS","progress","ni","heapAfter","e","stack"],"mappings":"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"}
|
package/build/types.cjs
CHANGED
|
@@ -58,7 +58,7 @@ var Control = /*#__PURE__*/ function(Control) {
|
|
|
58
58
|
return Control;
|
|
59
59
|
}({});
|
|
60
60
|
const CONTROL_SLOTS = Object.values(Control).length / 2;
|
|
61
|
-
const DEFAULT_CYCLES =
|
|
61
|
+
const DEFAULT_CYCLES = 10_000;
|
|
62
62
|
const Z95 = 1.96;
|
|
63
63
|
const DURATION_SCALE = 1000n;
|
|
64
64
|
const COMPLETE_VALUE = 100_00;
|
package/build/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface SetupFn<TContext> {\n (): MaybePromise<TContext>;\n}\n\nexport interface TeardownFn<TContext> {\n (ctx: TContext): MaybePromise<void>;\n}\n\nexport interface StepFn<TContext, TInput> {\n (ctx: TContext, input: TInput): MaybePromise<unknown>;\n}\n\nexport interface FeedFn<TInput> {\n (): MaybePromise<TInput>;\n}\n\ntype _Sequence<To extends number, R extends unknown[]> = R['length'] extends To ? R[number] : _Sequence<To, [R['length'], ...R]>;\nexport type Sequence<To extends number> = number extends To ? number : _Sequence<To, []>;\nexport type Between<From extends number, To extends number> = Exclude<Sequence<To>, Sequence<From>>;\n\nexport type ReportType =\n | 'ops'\n | 'min'\n | 'max'\n | 'mean'\n | 'median'\n | 'mode'\n | 'variance'\n | 'sd'\n | 'sem'\n | 'moe'\n | 'rme'\n | 'mad'\n | 'iqr'\n | 'ci_lower'\n | 'ci_upper'\n | `p${Between<1, 100>}`;\nexport type ReportTypeList = readonly ReportType[];\nexport const REPORT_TYPES: ReportTypeList = Array.from({ length: 99 }, (_, idx) => `p${idx + 1}` as ReportType).concat([\n 'ops',\n 'mean',\n 'min',\n 'max',\n 'median',\n 'mode',\n 'variance',\n 'sd',\n 'sem',\n 'moe',\n 'rme',\n 'mad',\n 'iqr',\n 'ci_lower',\n 'ci_upper',\n]);\n\nexport interface ReportOptions<R extends ReportTypeList> {\n reportTypes: R;\n}\n\nexport interface BenchmarkOptions {\n warmupCycles?: number;\n minCycles?: number;\n absThreshold?: number; // ns\n relThreshold?: number; // %\n gcObserver?: boolean;\n}\n\nexport interface RunOptions<TContext, TInput> {\n setup?: SetupFn<TContext>;\n teardown?: TeardownFn<TContext>;\n pre?: StepFn<TContext, TInput>;\n run: StepFn<TContext, TInput>;\n post?: StepFn<TContext, TInput>;\n data?: TInput;\n}\n\nexport interface ExecutorRunOptions<TContext, TInput> extends RunOptions<TContext, TInput> {\n id?: string;\n}\n\nexport interface WorkerOptions extends Required<BenchmarkOptions> {\n benchmarkUrl?: string;\n setupCode?: string;\n teardownCode?: string;\n preCode?: string;\n runCode: string;\n postCode?: string;\n data?: unknown;\n\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport interface Options<TContext, TInput> extends RunOptions<TContext, TInput>, BenchmarkOptions {\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport enum Control {\n INDEX,\n PROGRESS,\n COMPLETE,\n HEAP_USED,\n}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES =
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface SetupFn<TContext> {\n (): MaybePromise<TContext>;\n}\n\nexport interface TeardownFn<TContext> {\n (ctx: TContext): MaybePromise<void>;\n}\n\nexport interface StepFn<TContext, TInput> {\n (ctx: TContext, input: TInput): MaybePromise<unknown>;\n}\n\nexport interface FeedFn<TInput> {\n (): MaybePromise<TInput>;\n}\n\ntype _Sequence<To extends number, R extends unknown[]> = R['length'] extends To ? R[number] : _Sequence<To, [R['length'], ...R]>;\nexport type Sequence<To extends number> = number extends To ? number : _Sequence<To, []>;\nexport type Between<From extends number, To extends number> = Exclude<Sequence<To>, Sequence<From>>;\n\nexport type ReportType =\n | 'ops'\n | 'min'\n | 'max'\n | 'mean'\n | 'median'\n | 'mode'\n | 'variance'\n | 'sd'\n | 'sem'\n | 'moe'\n | 'rme'\n | 'mad'\n | 'iqr'\n | 'ci_lower'\n | 'ci_upper'\n | `p${Between<1, 100>}`;\nexport type ReportTypeList = readonly ReportType[];\nexport const REPORT_TYPES: ReportTypeList = Array.from({ length: 99 }, (_, idx) => `p${idx + 1}` as ReportType).concat([\n 'ops',\n 'mean',\n 'min',\n 'max',\n 'median',\n 'mode',\n 'variance',\n 'sd',\n 'sem',\n 'moe',\n 'rme',\n 'mad',\n 'iqr',\n 'ci_lower',\n 'ci_upper',\n]);\n\nexport interface ReportOptions<R extends ReportTypeList> {\n reportTypes: R;\n}\n\nexport interface BenchmarkOptions {\n warmupCycles?: number;\n minCycles?: number;\n absThreshold?: number; // ns\n relThreshold?: number; // %\n gcObserver?: boolean;\n}\n\nexport interface RunOptions<TContext, TInput> {\n setup?: SetupFn<TContext>;\n teardown?: TeardownFn<TContext>;\n pre?: StepFn<TContext, TInput>;\n run: StepFn<TContext, TInput>;\n post?: StepFn<TContext, TInput>;\n data?: TInput;\n}\n\nexport interface ExecutorRunOptions<TContext, TInput> extends RunOptions<TContext, TInput> {\n id?: string;\n}\n\nexport interface WorkerOptions extends Required<BenchmarkOptions> {\n benchmarkUrl?: string;\n setupCode?: string;\n teardownCode?: string;\n preCode?: string;\n runCode: string;\n postCode?: string;\n data?: unknown;\n\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport interface Options<TContext, TInput> extends RunOptions<TContext, TInput>, BenchmarkOptions {\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport enum Control {\n INDEX,\n PROGRESS,\n COMPLETE,\n HEAP_USED,\n}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 10_000;\nexport const Z95 = 1.96;\nexport const DURATION_SCALE = 1000n;\nexport const COMPLETE_VALUE = 100_00;\n\nexport interface ProgressInfo {\n id: string;\n progress: number;\n}\n\nexport type ProgressCallback = (info: ProgressInfo) => void;\n"],"names":["COMPLETE_VALUE","CONTROL_SLOTS","Control","DEFAULT_CYCLES","DURATION_SCALE","REPORT_TYPES","Z95","Array","from","length","_","idx","concat","Object","values"],"mappings":";;;;;;;;;;;QAgHaA;eAAAA;;QAJAC;eAAAA;;QAPDC;eAAAA;;QAQCC;eAAAA;;QAEAC;eAAAA;;QAvEAC;eAAAA;;QAsEAC;eAAAA;;;AAtEN,MAAMD,eAA+BE,MAAMC,IAAI,CAAC;IAAEC,QAAQ;AAAG,GAAG,CAACC,GAAGC,MAAQ,CAAC,CAAC,EAAEA,MAAM,GAAG,EAAgBC,MAAM,CAAC;IACrH;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AA6CM,IAAA,AAAKV,iCAAAA;;;;;WAAAA;;AAOL,MAAMD,gBAAgBY,OAAOC,MAAM,CAACZ,SAASO,MAAM,GAAG;AACtD,MAAMN,iBAAiB;AACvB,MAAMG,MAAM;AACZ,MAAMF,iBAAiB,KAAK;AAC5B,MAAMJ,iBAAiB"}
|
package/build/types.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare enum Control {
|
|
|
60
60
|
HEAP_USED = 3
|
|
61
61
|
}
|
|
62
62
|
export declare const CONTROL_SLOTS: number;
|
|
63
|
-
export declare const DEFAULT_CYCLES =
|
|
63
|
+
export declare const DEFAULT_CYCLES = 10000;
|
|
64
64
|
export declare const Z95 = 1.96;
|
|
65
65
|
export declare const DURATION_SCALE = 1000n;
|
|
66
66
|
export declare const COMPLETE_VALUE = 10000;
|
package/build/types.js
CHANGED
|
@@ -25,7 +25,7 @@ export var Control = /*#__PURE__*/ function(Control) {
|
|
|
25
25
|
return Control;
|
|
26
26
|
}({});
|
|
27
27
|
export const CONTROL_SLOTS = Object.values(Control).length / 2;
|
|
28
|
-
export const DEFAULT_CYCLES =
|
|
28
|
+
export const DEFAULT_CYCLES = 10_000;
|
|
29
29
|
export const Z95 = 1.96;
|
|
30
30
|
export const DURATION_SCALE = 1000n;
|
|
31
31
|
export const COMPLETE_VALUE = 100_00;
|
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface SetupFn<TContext> {\n (): MaybePromise<TContext>;\n}\n\nexport interface TeardownFn<TContext> {\n (ctx: TContext): MaybePromise<void>;\n}\n\nexport interface StepFn<TContext, TInput> {\n (ctx: TContext, input: TInput): MaybePromise<unknown>;\n}\n\nexport interface FeedFn<TInput> {\n (): MaybePromise<TInput>;\n}\n\ntype _Sequence<To extends number, R extends unknown[]> = R['length'] extends To ? R[number] : _Sequence<To, [R['length'], ...R]>;\nexport type Sequence<To extends number> = number extends To ? number : _Sequence<To, []>;\nexport type Between<From extends number, To extends number> = Exclude<Sequence<To>, Sequence<From>>;\n\nexport type ReportType =\n | 'ops'\n | 'min'\n | 'max'\n | 'mean'\n | 'median'\n | 'mode'\n | 'variance'\n | 'sd'\n | 'sem'\n | 'moe'\n | 'rme'\n | 'mad'\n | 'iqr'\n | 'ci_lower'\n | 'ci_upper'\n | `p${Between<1, 100>}`;\nexport type ReportTypeList = readonly ReportType[];\nexport const REPORT_TYPES: ReportTypeList = Array.from({ length: 99 }, (_, idx) => `p${idx + 1}` as ReportType).concat([\n 'ops',\n 'mean',\n 'min',\n 'max',\n 'median',\n 'mode',\n 'variance',\n 'sd',\n 'sem',\n 'moe',\n 'rme',\n 'mad',\n 'iqr',\n 'ci_lower',\n 'ci_upper',\n]);\n\nexport interface ReportOptions<R extends ReportTypeList> {\n reportTypes: R;\n}\n\nexport interface BenchmarkOptions {\n warmupCycles?: number;\n minCycles?: number;\n absThreshold?: number; // ns\n relThreshold?: number; // %\n gcObserver?: boolean;\n}\n\nexport interface RunOptions<TContext, TInput> {\n setup?: SetupFn<TContext>;\n teardown?: TeardownFn<TContext>;\n pre?: StepFn<TContext, TInput>;\n run: StepFn<TContext, TInput>;\n post?: StepFn<TContext, TInput>;\n data?: TInput;\n}\n\nexport interface ExecutorRunOptions<TContext, TInput> extends RunOptions<TContext, TInput> {\n id?: string;\n}\n\nexport interface WorkerOptions extends Required<BenchmarkOptions> {\n benchmarkUrl?: string;\n setupCode?: string;\n teardownCode?: string;\n preCode?: string;\n runCode: string;\n postCode?: string;\n data?: unknown;\n\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport interface Options<TContext, TInput> extends RunOptions<TContext, TInput>, BenchmarkOptions {\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport enum Control {\n INDEX,\n PROGRESS,\n COMPLETE,\n HEAP_USED,\n}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES =
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type MaybePromise<T> = Promise<T> | PromiseLike<T> | T;\n\nexport interface SetupFn<TContext> {\n (): MaybePromise<TContext>;\n}\n\nexport interface TeardownFn<TContext> {\n (ctx: TContext): MaybePromise<void>;\n}\n\nexport interface StepFn<TContext, TInput> {\n (ctx: TContext, input: TInput): MaybePromise<unknown>;\n}\n\nexport interface FeedFn<TInput> {\n (): MaybePromise<TInput>;\n}\n\ntype _Sequence<To extends number, R extends unknown[]> = R['length'] extends To ? R[number] : _Sequence<To, [R['length'], ...R]>;\nexport type Sequence<To extends number> = number extends To ? number : _Sequence<To, []>;\nexport type Between<From extends number, To extends number> = Exclude<Sequence<To>, Sequence<From>>;\n\nexport type ReportType =\n | 'ops'\n | 'min'\n | 'max'\n | 'mean'\n | 'median'\n | 'mode'\n | 'variance'\n | 'sd'\n | 'sem'\n | 'moe'\n | 'rme'\n | 'mad'\n | 'iqr'\n | 'ci_lower'\n | 'ci_upper'\n | `p${Between<1, 100>}`;\nexport type ReportTypeList = readonly ReportType[];\nexport const REPORT_TYPES: ReportTypeList = Array.from({ length: 99 }, (_, idx) => `p${idx + 1}` as ReportType).concat([\n 'ops',\n 'mean',\n 'min',\n 'max',\n 'median',\n 'mode',\n 'variance',\n 'sd',\n 'sem',\n 'moe',\n 'rme',\n 'mad',\n 'iqr',\n 'ci_lower',\n 'ci_upper',\n]);\n\nexport interface ReportOptions<R extends ReportTypeList> {\n reportTypes: R;\n}\n\nexport interface BenchmarkOptions {\n warmupCycles?: number;\n minCycles?: number;\n absThreshold?: number; // ns\n relThreshold?: number; // %\n gcObserver?: boolean;\n}\n\nexport interface RunOptions<TContext, TInput> {\n setup?: SetupFn<TContext>;\n teardown?: TeardownFn<TContext>;\n pre?: StepFn<TContext, TInput>;\n run: StepFn<TContext, TInput>;\n post?: StepFn<TContext, TInput>;\n data?: TInput;\n}\n\nexport interface ExecutorRunOptions<TContext, TInput> extends RunOptions<TContext, TInput> {\n id?: string;\n}\n\nexport interface WorkerOptions extends Required<BenchmarkOptions> {\n benchmarkUrl?: string;\n setupCode?: string;\n teardownCode?: string;\n preCode?: string;\n runCode: string;\n postCode?: string;\n data?: unknown;\n\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport interface Options<TContext, TInput> extends RunOptions<TContext, TInput>, BenchmarkOptions {\n durationsSAB: SharedArrayBuffer;\n controlSAB: SharedArrayBuffer;\n}\n\nexport enum Control {\n INDEX,\n PROGRESS,\n COMPLETE,\n HEAP_USED,\n}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 10_000;\nexport const Z95 = 1.96;\nexport const DURATION_SCALE = 1000n;\nexport const COMPLETE_VALUE = 100_00;\n\nexport interface ProgressInfo {\n id: string;\n progress: number;\n}\n\nexport type ProgressCallback = (info: ProgressInfo) => void;\n"],"names":["REPORT_TYPES","Array","from","length","_","idx","concat","Control","CONTROL_SLOTS","Object","values","DEFAULT_CYCLES","Z95","DURATION_SCALE","COMPLETE_VALUE"],"mappings":"AAwCA,OAAO,MAAMA,eAA+BC,MAAMC,IAAI,CAAC;IAAEC,QAAQ;AAAG,GAAG,CAACC,GAAGC,MAAQ,CAAC,CAAC,EAAEA,MAAM,GAAG,EAAgBC,MAAM,CAAC;IACrH;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,EAAE;AA6CH,OAAO,IAAA,AAAKC,iCAAAA;;;;;WAAAA;MAKX;AAED,OAAO,MAAMC,gBAAgBC,OAAOC,MAAM,CAACH,SAASJ,MAAM,GAAG,EAAE;AAC/D,OAAO,MAAMQ,iBAAiB,OAAO;AACrC,OAAO,MAAMC,MAAM,KAAK;AACxB,OAAO,MAAMC,iBAAiB,KAAK,CAAC;AACpC,OAAO,MAAMC,iBAAiB,OAAO"}
|
package/build/utils.cjs
CHANGED
|
@@ -15,6 +15,9 @@ _export(exports, {
|
|
|
15
15
|
get abs () {
|
|
16
16
|
return abs;
|
|
17
17
|
},
|
|
18
|
+
get assertNoClosure () {
|
|
19
|
+
return assertNoClosure;
|
|
20
|
+
},
|
|
18
21
|
get cmp () {
|
|
19
22
|
return cmp;
|
|
20
23
|
},
|
|
@@ -27,6 +30,9 @@ _export(exports, {
|
|
|
27
30
|
get divs () {
|
|
28
31
|
return divs;
|
|
29
32
|
},
|
|
33
|
+
get isqrt () {
|
|
34
|
+
return isqrt;
|
|
35
|
+
},
|
|
30
36
|
get max () {
|
|
31
37
|
return max;
|
|
32
38
|
},
|
|
@@ -35,6 +41,17 @@ _export(exports, {
|
|
|
35
41
|
}
|
|
36
42
|
});
|
|
37
43
|
const _core = require("@swc/core");
|
|
44
|
+
const isqrt = (n)=>{
|
|
45
|
+
if (n < 0n) throw new RangeError('Square root of negative');
|
|
46
|
+
if (n < 2n) return n;
|
|
47
|
+
let x = n;
|
|
48
|
+
let y = x + 1n >> 1n;
|
|
49
|
+
while(y < x){
|
|
50
|
+
x = y;
|
|
51
|
+
y = x + n / x >> 1n;
|
|
52
|
+
}
|
|
53
|
+
return x;
|
|
54
|
+
};
|
|
38
55
|
const abs = (value)=>{
|
|
39
56
|
if (value < 0n) {
|
|
40
57
|
return -value;
|
|
@@ -100,6 +117,42 @@ class ScaledBigInt {
|
|
|
100
117
|
return Number(div(this.value, this.scale));
|
|
101
118
|
}
|
|
102
119
|
}
|
|
120
|
+
const KNOWN_GLOBALS = new Set(Object.getOwnPropertyNames(globalThis));
|
|
121
|
+
KNOWN_GLOBALS.add('arguments');
|
|
122
|
+
function collectUnresolved(node, result) {
|
|
123
|
+
if (!node || typeof node !== 'object') return;
|
|
124
|
+
if (Array.isArray(node)) {
|
|
125
|
+
for (const item of node)collectUnresolved(item, result);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const obj = node;
|
|
129
|
+
if (obj.type === 'Identifier' && obj.ctxt === 1 && typeof obj.value === 'string') {
|
|
130
|
+
result.add(obj.value);
|
|
131
|
+
}
|
|
132
|
+
for (const key of Object.keys(obj)){
|
|
133
|
+
if (key === 'span') continue;
|
|
134
|
+
collectUnresolved(obj[key], result);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function assertNoClosure(code, name) {
|
|
138
|
+
let ast;
|
|
139
|
+
try {
|
|
140
|
+
ast = (0, _core.parseSync)(`var __fn = ${code}`, {
|
|
141
|
+
syntax: 'ecmascript',
|
|
142
|
+
target: 'esnext'
|
|
143
|
+
});
|
|
144
|
+
} catch {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const unresolved = new Set();
|
|
148
|
+
collectUnresolved(ast, unresolved);
|
|
149
|
+
for (const g of KNOWN_GLOBALS)unresolved.delete(g);
|
|
150
|
+
if (unresolved.size === 0) return;
|
|
151
|
+
const vars = [
|
|
152
|
+
...unresolved
|
|
153
|
+
].join(', ');
|
|
154
|
+
throw new Error(`Benchmark "${name}" function references outer-scope variables: ${vars}\n\n` + `Benchmark functions are serialized with .toString() and executed in an isolated\n` + `worker thread. Closed-over variables from the original module scope are not\n` + `available in the worker and will cause a ReferenceError at runtime.\n\n` + `To fix this, move the referenced values into:\n` + ` - "setup" function (returned value becomes the first argument of run/pre/post)\n` + ` - "data" option (passed as the second argument of run/pre/post)`);
|
|
155
|
+
}
|
|
103
156
|
const transpile = async (code)=>{
|
|
104
157
|
const output = await (0, _core.transform)(code, {
|
|
105
158
|
filename: 'benchmark.ts',
|
package/build/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { transform } from '@swc/core';\n\nexport const abs = (value: bigint) => {\n if (value < 0n) {\n return -value;\n }\n return value;\n};\nexport const cmp = (a: bigint | number, b: bigint | number): number => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n};\n\nexport const max = (a: bigint, b: bigint) => {\n if (a > b) {\n return a;\n }\n return b;\n};\n\nexport const divMod = (a: bigint, b: bigint) => {\n return { quotient: a / b, remainder: a % b };\n};\n\nexport function div(a: bigint, b: bigint, decimals: number = 2): string {\n if (b === 0n) throw new RangeError('Division by zero');\n const scale = 10n ** BigInt(decimals);\n const scaled = (a * scale) / b;\n const intPart = scaled / scale;\n const fracPart = scaled % scale;\n return `${intPart}.${fracPart.toString().padStart(decimals, '0')}`;\n}\n\nexport function divs(a: bigint, b: bigint, scale: bigint): bigint {\n if (b === 0n) throw new RangeError('Division by zero');\n return (a * scale) / b;\n}\n\nexport class ScaledBigInt {\n constructor(\n public value: bigint,\n public scale: bigint,\n ) {}\n add(value: bigint) {\n this.value += value * this.scale;\n }\n sub(value: bigint) {\n this.value -= value * this.scale;\n }\n div(value: bigint) {\n this.value /= value;\n }\n mul(value: bigint) {\n this.value *= value;\n }\n unscale() {\n return this.value / this.scale;\n }\n number() {\n return Number(div(this.value, this.scale));\n }\n}\n\nexport const transpile = async (code: string): Promise<string> => {\n const output = await transform(code, {\n filename: 'benchmark.ts',\n jsc: {\n parser: {\n syntax: 'typescript',\n tsx: false,\n dynamicImport: true,\n },\n target: 'esnext',\n },\n module: {\n type: 'es6',\n },\n });\n return output.code;\n};\n"],"names":["ScaledBigInt","abs","cmp","div","divMod","divs","max","transpile","value","a","b","quotient","remainder","decimals","
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { transform, parseSync } from '@swc/core';\n\nexport const isqrt = (n: bigint): bigint => {\n if (n < 0n) throw new RangeError('Square root of negative');\n if (n < 2n) return n;\n let x = n;\n let y = (x + 1n) >> 1n;\n while (y < x) {\n x = y;\n y = (x + n / x) >> 1n;\n }\n return x;\n};\n\nexport const abs = (value: bigint) => {\n if (value < 0n) {\n return -value;\n }\n return value;\n};\nexport const cmp = (a: bigint | number, b: bigint | number): number => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n};\n\nexport const max = (a: bigint, b: bigint) => {\n if (a > b) {\n return a;\n }\n return b;\n};\n\nexport const divMod = (a: bigint, b: bigint) => {\n return { quotient: a / b, remainder: a % b };\n};\n\nexport function div(a: bigint, b: bigint, decimals: number = 2): string {\n if (b === 0n) throw new RangeError('Division by zero');\n const scale = 10n ** BigInt(decimals);\n const scaled = (a * scale) / b;\n const intPart = scaled / scale;\n const fracPart = scaled % scale;\n return `${intPart}.${fracPart.toString().padStart(decimals, '0')}`;\n}\n\nexport function divs(a: bigint, b: bigint, scale: bigint): bigint {\n if (b === 0n) throw new RangeError('Division by zero');\n return (a * scale) / b;\n}\n\nexport class ScaledBigInt {\n constructor(\n public value: bigint,\n public scale: bigint,\n ) {}\n add(value: bigint) {\n this.value += value * this.scale;\n }\n sub(value: bigint) {\n this.value -= value * this.scale;\n }\n div(value: bigint) {\n this.value /= value;\n }\n mul(value: bigint) {\n this.value *= value;\n }\n unscale() {\n return this.value / this.scale;\n }\n number() {\n return Number(div(this.value, this.scale));\n }\n}\n\nconst KNOWN_GLOBALS = new Set(Object.getOwnPropertyNames(globalThis));\nKNOWN_GLOBALS.add('arguments');\n\nfunction collectUnresolved(node: unknown, result: Set<string>) {\n if (!node || typeof node !== 'object') return;\n if (Array.isArray(node)) {\n for (const item of node) collectUnresolved(item, result);\n return;\n }\n const obj = node as Record<string, unknown>;\n if (obj.type === 'Identifier' && obj.ctxt === 1 && typeof obj.value === 'string') {\n result.add(obj.value);\n }\n for (const key of Object.keys(obj)) {\n if (key === 'span') continue;\n collectUnresolved(obj[key], result);\n }\n}\n\nexport function assertNoClosure(code: string, name: string): void {\n let ast;\n try {\n ast = parseSync(`var __fn = ${code}`, { syntax: 'ecmascript', target: 'esnext' });\n } catch {\n return;\n }\n const unresolved = new Set<string>();\n collectUnresolved(ast, unresolved);\n for (const g of KNOWN_GLOBALS) unresolved.delete(g);\n if (unresolved.size === 0) return;\n\n const vars = [...unresolved].join(', ');\n throw new Error(\n `Benchmark \"${name}\" function references outer-scope variables: ${vars}\\n\\n` +\n `Benchmark functions are serialized with .toString() and executed in an isolated\\n` +\n `worker thread. Closed-over variables from the original module scope are not\\n` +\n `available in the worker and will cause a ReferenceError at runtime.\\n\\n` +\n `To fix this, move the referenced values into:\\n` +\n ` - \"setup\" function (returned value becomes the first argument of run/pre/post)\\n` +\n ` - \"data\" option (passed as the second argument of run/pre/post)`,\n );\n}\n\nexport const transpile = async (code: string): Promise<string> => {\n const output = await transform(code, {\n filename: 'benchmark.ts',\n jsc: {\n parser: {\n syntax: 'typescript',\n tsx: false,\n dynamicImport: true,\n },\n target: 'esnext',\n },\n module: {\n type: 'es6',\n },\n });\n return output.code;\n};\n"],"names":["ScaledBigInt","abs","assertNoClosure","cmp","div","divMod","divs","isqrt","max","transpile","n","RangeError","x","y","value","a","b","quotient","remainder","decimals","scale","BigInt","scaled","intPart","fracPart","toString","padStart","add","sub","mul","unscale","number","Number","KNOWN_GLOBALS","Set","Object","getOwnPropertyNames","globalThis","collectUnresolved","node","result","Array","isArray","item","obj","type","ctxt","key","keys","code","name","ast","parseSync","syntax","target","unresolved","g","delete","size","vars","join","Error","output","transform","filename","jsc","parser","tsx","dynamicImport","module"],"mappings":"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"}
|
package/build/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const isqrt: (n: bigint) => bigint;
|
|
1
2
|
export declare const abs: (value: bigint) => bigint;
|
|
2
3
|
export declare const cmp: (a: bigint | number, b: bigint | number) => number;
|
|
3
4
|
export declare const max: (a: bigint, b: bigint) => bigint;
|
|
@@ -18,4 +19,5 @@ export declare class ScaledBigInt {
|
|
|
18
19
|
unscale(): bigint;
|
|
19
20
|
number(): number;
|
|
20
21
|
}
|
|
22
|
+
export declare function assertNoClosure(code: string, name: string): void;
|
|
21
23
|
export declare const transpile: (code: string) => Promise<string>;
|
package/build/utils.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import { transform } from '@swc/core';
|
|
1
|
+
import { transform, parseSync } from '@swc/core';
|
|
2
|
+
export const isqrt = (n)=>{
|
|
3
|
+
if (n < 0n) throw new RangeError('Square root of negative');
|
|
4
|
+
if (n < 2n) return n;
|
|
5
|
+
let x = n;
|
|
6
|
+
let y = x + 1n >> 1n;
|
|
7
|
+
while(y < x){
|
|
8
|
+
x = y;
|
|
9
|
+
y = x + n / x >> 1n;
|
|
10
|
+
}
|
|
11
|
+
return x;
|
|
12
|
+
};
|
|
2
13
|
export const abs = (value)=>{
|
|
3
14
|
if (value < 0n) {
|
|
4
15
|
return -value;
|
|
@@ -64,6 +75,42 @@ export class ScaledBigInt {
|
|
|
64
75
|
return Number(div(this.value, this.scale));
|
|
65
76
|
}
|
|
66
77
|
}
|
|
78
|
+
const KNOWN_GLOBALS = new Set(Object.getOwnPropertyNames(globalThis));
|
|
79
|
+
KNOWN_GLOBALS.add('arguments');
|
|
80
|
+
function collectUnresolved(node, result) {
|
|
81
|
+
if (!node || typeof node !== 'object') return;
|
|
82
|
+
if (Array.isArray(node)) {
|
|
83
|
+
for (const item of node)collectUnresolved(item, result);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const obj = node;
|
|
87
|
+
if (obj.type === 'Identifier' && obj.ctxt === 1 && typeof obj.value === 'string') {
|
|
88
|
+
result.add(obj.value);
|
|
89
|
+
}
|
|
90
|
+
for (const key of Object.keys(obj)){
|
|
91
|
+
if (key === 'span') continue;
|
|
92
|
+
collectUnresolved(obj[key], result);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function assertNoClosure(code, name) {
|
|
96
|
+
let ast;
|
|
97
|
+
try {
|
|
98
|
+
ast = parseSync(`var __fn = ${code}`, {
|
|
99
|
+
syntax: 'ecmascript',
|
|
100
|
+
target: 'esnext'
|
|
101
|
+
});
|
|
102
|
+
} catch {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const unresolved = new Set();
|
|
106
|
+
collectUnresolved(ast, unresolved);
|
|
107
|
+
for (const g of KNOWN_GLOBALS)unresolved.delete(g);
|
|
108
|
+
if (unresolved.size === 0) return;
|
|
109
|
+
const vars = [
|
|
110
|
+
...unresolved
|
|
111
|
+
].join(', ');
|
|
112
|
+
throw new Error(`Benchmark "${name}" function references outer-scope variables: ${vars}\n\n` + `Benchmark functions are serialized with .toString() and executed in an isolated\n` + `worker thread. Closed-over variables from the original module scope are not\n` + `available in the worker and will cause a ReferenceError at runtime.\n\n` + `To fix this, move the referenced values into:\n` + ` - "setup" function (returned value becomes the first argument of run/pre/post)\n` + ` - "data" option (passed as the second argument of run/pre/post)`);
|
|
113
|
+
}
|
|
67
114
|
export const transpile = async (code)=>{
|
|
68
115
|
const output = await transform(code, {
|
|
69
116
|
filename: 'benchmark.ts',
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { transform } from '@swc/core';\n\nexport const abs = (value: bigint) => {\n if (value < 0n) {\n return -value;\n }\n return value;\n};\nexport const cmp = (a: bigint | number, b: bigint | number): number => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n};\n\nexport const max = (a: bigint, b: bigint) => {\n if (a > b) {\n return a;\n }\n return b;\n};\n\nexport const divMod = (a: bigint, b: bigint) => {\n return { quotient: a / b, remainder: a % b };\n};\n\nexport function div(a: bigint, b: bigint, decimals: number = 2): string {\n if (b === 0n) throw new RangeError('Division by zero');\n const scale = 10n ** BigInt(decimals);\n const scaled = (a * scale) / b;\n const intPart = scaled / scale;\n const fracPart = scaled % scale;\n return `${intPart}.${fracPart.toString().padStart(decimals, '0')}`;\n}\n\nexport function divs(a: bigint, b: bigint, scale: bigint): bigint {\n if (b === 0n) throw new RangeError('Division by zero');\n return (a * scale) / b;\n}\n\nexport class ScaledBigInt {\n constructor(\n public value: bigint,\n public scale: bigint,\n ) {}\n add(value: bigint) {\n this.value += value * this.scale;\n }\n sub(value: bigint) {\n this.value -= value * this.scale;\n }\n div(value: bigint) {\n this.value /= value;\n }\n mul(value: bigint) {\n this.value *= value;\n }\n unscale() {\n return this.value / this.scale;\n }\n number() {\n return Number(div(this.value, this.scale));\n }\n}\n\nexport const transpile = async (code: string): Promise<string> => {\n const output = await transform(code, {\n filename: 'benchmark.ts',\n jsc: {\n parser: {\n syntax: 'typescript',\n tsx: false,\n dynamicImport: true,\n },\n target: 'esnext',\n },\n module: {\n type: 'es6',\n },\n });\n return output.code;\n};\n"],"names":["transform","abs","value","cmp","a","b","max","divMod","quotient","remainder","div","decimals","
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import { transform, parseSync } from '@swc/core';\n\nexport const isqrt = (n: bigint): bigint => {\n if (n < 0n) throw new RangeError('Square root of negative');\n if (n < 2n) return n;\n let x = n;\n let y = (x + 1n) >> 1n;\n while (y < x) {\n x = y;\n y = (x + n / x) >> 1n;\n }\n return x;\n};\n\nexport const abs = (value: bigint) => {\n if (value < 0n) {\n return -value;\n }\n return value;\n};\nexport const cmp = (a: bigint | number, b: bigint | number): number => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n};\n\nexport const max = (a: bigint, b: bigint) => {\n if (a > b) {\n return a;\n }\n return b;\n};\n\nexport const divMod = (a: bigint, b: bigint) => {\n return { quotient: a / b, remainder: a % b };\n};\n\nexport function div(a: bigint, b: bigint, decimals: number = 2): string {\n if (b === 0n) throw new RangeError('Division by zero');\n const scale = 10n ** BigInt(decimals);\n const scaled = (a * scale) / b;\n const intPart = scaled / scale;\n const fracPart = scaled % scale;\n return `${intPart}.${fracPart.toString().padStart(decimals, '0')}`;\n}\n\nexport function divs(a: bigint, b: bigint, scale: bigint): bigint {\n if (b === 0n) throw new RangeError('Division by zero');\n return (a * scale) / b;\n}\n\nexport class ScaledBigInt {\n constructor(\n public value: bigint,\n public scale: bigint,\n ) {}\n add(value: bigint) {\n this.value += value * this.scale;\n }\n sub(value: bigint) {\n this.value -= value * this.scale;\n }\n div(value: bigint) {\n this.value /= value;\n }\n mul(value: bigint) {\n this.value *= value;\n }\n unscale() {\n return this.value / this.scale;\n }\n number() {\n return Number(div(this.value, this.scale));\n }\n}\n\nconst KNOWN_GLOBALS = new Set(Object.getOwnPropertyNames(globalThis));\nKNOWN_GLOBALS.add('arguments');\n\nfunction collectUnresolved(node: unknown, result: Set<string>) {\n if (!node || typeof node !== 'object') return;\n if (Array.isArray(node)) {\n for (const item of node) collectUnresolved(item, result);\n return;\n }\n const obj = node as Record<string, unknown>;\n if (obj.type === 'Identifier' && obj.ctxt === 1 && typeof obj.value === 'string') {\n result.add(obj.value);\n }\n for (const key of Object.keys(obj)) {\n if (key === 'span') continue;\n collectUnresolved(obj[key], result);\n }\n}\n\nexport function assertNoClosure(code: string, name: string): void {\n let ast;\n try {\n ast = parseSync(`var __fn = ${code}`, { syntax: 'ecmascript', target: 'esnext' });\n } catch {\n return;\n }\n const unresolved = new Set<string>();\n collectUnresolved(ast, unresolved);\n for (const g of KNOWN_GLOBALS) unresolved.delete(g);\n if (unresolved.size === 0) return;\n\n const vars = [...unresolved].join(', ');\n throw new Error(\n `Benchmark \"${name}\" function references outer-scope variables: ${vars}\\n\\n` +\n `Benchmark functions are serialized with .toString() and executed in an isolated\\n` +\n `worker thread. Closed-over variables from the original module scope are not\\n` +\n `available in the worker and will cause a ReferenceError at runtime.\\n\\n` +\n `To fix this, move the referenced values into:\\n` +\n ` - \"setup\" function (returned value becomes the first argument of run/pre/post)\\n` +\n ` - \"data\" option (passed as the second argument of run/pre/post)`,\n );\n}\n\nexport const transpile = async (code: string): Promise<string> => {\n const output = await transform(code, {\n filename: 'benchmark.ts',\n jsc: {\n parser: {\n syntax: 'typescript',\n tsx: false,\n dynamicImport: true,\n },\n target: 'esnext',\n },\n module: {\n type: 'es6',\n },\n });\n return output.code;\n};\n"],"names":["transform","parseSync","isqrt","n","RangeError","x","y","abs","value","cmp","a","b","max","divMod","quotient","remainder","div","decimals","scale","BigInt","scaled","intPart","fracPart","toString","padStart","divs","ScaledBigInt","add","sub","mul","unscale","number","Number","KNOWN_GLOBALS","Set","Object","getOwnPropertyNames","globalThis","collectUnresolved","node","result","Array","isArray","item","obj","type","ctxt","key","keys","assertNoClosure","code","name","ast","syntax","target","unresolved","g","delete","size","vars","join","Error","transpile","output","filename","jsc","parser","tsx","dynamicImport","module"],"mappings":"AAAA,SAASA,SAAS,EAAEC,SAAS,QAAQ,YAAY;AAEjD,OAAO,MAAMC,QAAQ,CAACC;IACpB,IAAIA,IAAI,EAAE,EAAE,MAAM,IAAIC,WAAW;IACjC,IAAID,IAAI,EAAE,EAAE,OAAOA;IACnB,IAAIE,IAAIF;IACR,IAAIG,IAAI,AAACD,IAAI,EAAE,IAAK,EAAE;IACtB,MAAOC,IAAID,EAAG;QACZA,IAAIC;QACJA,IAAI,AAACD,IAAIF,IAAIE,KAAM,EAAE;IACvB;IACA,OAAOA;AACT,EAAE;AAEF,OAAO,MAAME,MAAM,CAACC;IAClB,IAAIA,QAAQ,EAAE,EAAE;QACd,OAAO,CAACA;IACV;IACA,OAAOA;AACT,EAAE;AACF,OAAO,MAAMC,MAAM,CAACC,GAAoBC;IACtC,IAAID,IAAIC,GAAG;QACT,OAAO;IACT;IACA,IAAID,IAAIC,GAAG;QACT,OAAO,CAAC;IACV;IACA,OAAO;AACT,EAAE;AAEF,OAAO,MAAMC,MAAM,CAACF,GAAWC;IAC7B,IAAID,IAAIC,GAAG;QACT,OAAOD;IACT;IACA,OAAOC;AACT,EAAE;AAEF,OAAO,MAAME,SAAS,CAACH,GAAWC;IAChC,OAAO;QAAEG,UAAUJ,IAAIC;QAAGI,WAAWL,IAAIC;IAAE;AAC7C,EAAE;AAEF,OAAO,SAASK,IAAIN,CAAS,EAAEC,CAAS,EAAEM,WAAmB,CAAC;IAC5D,IAAIN,MAAM,EAAE,EAAE,MAAM,IAAIP,WAAW;IACnC,MAAMc,QAAQ,GAAG,IAAIC,OAAOF;IAC5B,MAAMG,SAAS,AAACV,IAAIQ,QAASP;IAC7B,MAAMU,UAAUD,SAASF;IACzB,MAAMI,WAAWF,SAASF;IAC1B,OAAO,GAAGG,QAAQ,CAAC,EAAEC,SAASC,QAAQ,GAAGC,QAAQ,CAACP,UAAU,MAAM;AACpE;AAEA,OAAO,SAASQ,KAAKf,CAAS,EAAEC,CAAS,EAAEO,KAAa;IACtD,IAAIP,MAAM,EAAE,EAAE,MAAM,IAAIP,WAAW;IACnC,OAAO,AAACM,IAAIQ,QAASP;AACvB;AAEA,OAAO,MAAMe;;;IACX,YACE,AAAOlB,KAAa,EACpB,AAAOU,KAAa,CACpB;aAFOV,QAAAA;aACAU,QAAAA;IACN;IACHS,IAAInB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACU,KAAK;IAClC;IACAU,IAAIpB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACU,KAAK;IAClC;IACAF,IAAIR,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAqB,IAAIrB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAsB,UAAU;QACR,OAAO,IAAI,CAACtB,KAAK,GAAG,IAAI,CAACU,KAAK;IAChC;IACAa,SAAS;QACP,OAAOC,OAAOhB,IAAI,IAAI,CAACR,KAAK,EAAE,IAAI,CAACU,KAAK;IAC1C;AACF;AAEA,MAAMe,gBAAgB,IAAIC,IAAIC,OAAOC,mBAAmB,CAACC;AACzDJ,cAAcN,GAAG,CAAC;AAElB,SAASW,kBAAkBC,IAAa,EAAEC,MAAmB;IAC3D,IAAI,CAACD,QAAQ,OAAOA,SAAS,UAAU;IACvC,IAAIE,MAAMC,OAAO,CAACH,OAAO;QACvB,KAAK,MAAMI,QAAQJ,KAAMD,kBAAkBK,MAAMH;QACjD;IACF;IACA,MAAMI,MAAML;IACZ,IAAIK,IAAIC,IAAI,KAAK,gBAAgBD,IAAIE,IAAI,KAAK,KAAK,OAAOF,IAAIpC,KAAK,KAAK,UAAU;QAChFgC,OAAOb,GAAG,CAACiB,IAAIpC,KAAK;IACtB;IACA,KAAK,MAAMuC,OAAOZ,OAAOa,IAAI,CAACJ,KAAM;QAClC,IAAIG,QAAQ,QAAQ;QACpBT,kBAAkBM,GAAG,CAACG,IAAI,EAAEP;IAC9B;AACF;AAEA,OAAO,SAASS,gBAAgBC,IAAY,EAAEC,IAAY;IACxD,IAAIC;IACJ,IAAI;QACFA,MAAMnD,UAAU,CAAC,WAAW,EAAEiD,MAAM,EAAE;YAAEG,QAAQ;YAAcC,QAAQ;QAAS;IACjF,EAAE,OAAM;QACN;IACF;IACA,MAAMC,aAAa,IAAIrB;IACvBI,kBAAkBc,KAAKG;IACvB,KAAK,MAAMC,KAAKvB,cAAesB,WAAWE,MAAM,CAACD;IACjD,IAAID,WAAWG,IAAI,KAAK,GAAG;IAE3B,MAAMC,OAAO;WAAIJ;KAAW,CAACK,IAAI,CAAC;IAClC,MAAM,IAAIC,MACR,CAAC,WAAW,EAAEV,KAAK,6CAA6C,EAAEQ,KAAK,IAAI,CAAC,GAC1E,CAAC,iFAAiF,CAAC,GACnF,CAAC,6EAA6E,CAAC,GAC/E,CAAC,uEAAuE,CAAC,GACzE,CAAC,+CAA+C,CAAC,GACjD,CAAC,kFAAkF,CAAC,GACpF,CAAC,iEAAiE,CAAC;AAEzE;AAEA,OAAO,MAAMG,YAAY,OAAOZ;IAC9B,MAAMa,SAAS,MAAM/D,UAAUkD,MAAM;QACnCc,UAAU;QACVC,KAAK;YACHC,QAAQ;gBACNb,QAAQ;gBACRc,KAAK;gBACLC,eAAe;YACjB;YACAd,QAAQ;QACV;QACAe,QAAQ;YACNxB,MAAM;QACR;IACF;IACA,OAAOkB,OAAOb,IAAI;AACpB,EAAE"}
|
package/build/worker.cjs
CHANGED
|
@@ -64,7 +64,11 @@ const resolveSpecifier = (specifier)=>{
|
|
|
64
64
|
if ((0, _nodepath.isAbsolute)(specifier)) {
|
|
65
65
|
return (0, _nodeurl.pathToFileURL)(specifier).href;
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
try {
|
|
68
|
+
return requireFrom.resolve(specifier);
|
|
69
|
+
} catch {
|
|
70
|
+
return specifier;
|
|
71
|
+
}
|
|
68
72
|
};
|
|
69
73
|
const source = `
|
|
70
74
|
export const setup = ${serialize(setupCode)};
|
|
@@ -73,11 +77,6 @@ export const pre = ${serialize(preCode)};
|
|
|
73
77
|
export const run = ${serialize(runCode)};
|
|
74
78
|
export const post = ${serialize(postCode)};
|
|
75
79
|
`;
|
|
76
|
-
const globals = Object.create(null);
|
|
77
|
-
for (const k of Object.getOwnPropertyNames(globalThis)){
|
|
78
|
-
globals[k] = globalThis[k];
|
|
79
|
-
}
|
|
80
|
-
const context = (0, _nodevm.createContext)(globals);
|
|
81
80
|
const imports = new Map();
|
|
82
81
|
const createSyntheticModule = (moduleExports, exportNames, identifier)=>{
|
|
83
82
|
const mod = new _nodevm.SyntheticModule(exportNames, ()=>{
|
|
@@ -89,8 +88,7 @@ const createSyntheticModule = (moduleExports, exportNames, identifier)=>{
|
|
|
89
88
|
mod.setExport(name, moduleExports[name]);
|
|
90
89
|
}
|
|
91
90
|
}, {
|
|
92
|
-
identifier
|
|
93
|
-
context
|
|
91
|
+
identifier
|
|
94
92
|
});
|
|
95
93
|
return mod;
|
|
96
94
|
};
|
|
@@ -124,7 +122,6 @@ const loadDynamicModule = async (target)=>{
|
|
|
124
122
|
};
|
|
125
123
|
const mod = new _nodevm.SourceTextModule(source, {
|
|
126
124
|
identifier: resolvedBenchmarkUrl,
|
|
127
|
-
context,
|
|
128
125
|
initializeImportMeta (meta) {
|
|
129
126
|
meta.url = resolvedBenchmarkUrl;
|
|
130
127
|
},
|