overtake 1.0.4 → 1.1.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 +68 -25
- package/bin/overtake.js +1 -1
- package/build/cli.cjs +44 -33
- package/build/cli.cjs.map +1 -1
- package/build/cli.js +43 -32
- package/build/cli.js.map +1 -1
- package/build/executor.cjs +6 -3
- package/build/executor.cjs.map +1 -1
- package/build/executor.d.ts +3 -2
- package/build/executor.js +6 -3
- package/build/executor.js.map +1 -1
- package/build/gc-watcher.cjs +31 -0
- package/build/gc-watcher.cjs.map +1 -0
- package/build/gc-watcher.d.ts +9 -0
- package/build/gc-watcher.js +21 -0
- package/build/gc-watcher.js.map +1 -0
- package/build/index.cjs +9 -1
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +9 -1
- package/build/index.js.map +1 -1
- package/build/runner.cjs +226 -18
- package/build/runner.cjs.map +1 -1
- package/build/runner.d.ts +1 -1
- package/build/runner.js +226 -18
- package/build/runner.js.map +1 -1
- package/build/types.cjs.map +1 -1
- package/build/types.d.ts +4 -0
- package/build/types.js.map +1 -1
- package/build/utils.cjs +21 -0
- package/build/utils.cjs.map +1 -1
- package/build/utils.d.ts +1 -0
- package/build/utils.js +18 -0
- package/build/utils.js.map +1 -1
- package/build/worker.cjs +95 -8
- package/build/worker.cjs.map +1 -1
- package/build/worker.js +54 -8
- package/build/worker.js.map +1 -1
- package/examples/accuracy.ts +54 -0
- package/examples/complete.ts +3 -3
- package/examples/custom-reports.ts +21 -0
- package/examples/imports.ts +47 -0
- package/examples/quick-start.ts +10 -9
- package/package.json +10 -9
- package/src/cli.ts +46 -30
- package/src/executor.ts +8 -2
- package/src/gc-watcher.ts +23 -0
- package/src/index.ts +11 -0
- package/src/runner.ts +266 -17
- package/src/types.ts +4 -0
- package/src/utils.ts +20 -0
- package/src/worker.ts +59 -9
- package/CLAUDE.md +0 -145
- package/examples/array-copy.ts +0 -17
- package/examples/object-merge.ts +0 -41
- package/examples/serialization.ts +0 -22
package/build/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { Options, Control } from './types.js';\n\nconst COMPLETE_VALUE = 100_00;\n\nconst runSync = (run: Function) => {\n return (...args: unknown[]) => {\n const start = process.hrtime.bigint();\n run(...args);\n return process.hrtime.bigint() - start;\n };\n};\n\nconst runAsync = (run: Function) => {\n return async (...args: unknown[]) => {\n const start = process.hrtime.bigint();\n await run(...args);\n return process.hrtime.bigint() - start;\n };\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\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\n const context = (await setup?.()) as TContext;\n const maxCycles = durations.length;\n\n try {\n await pre?.(context, data!);\n const result = runRaw(context, data!);\n await post?.(context, data!);\n const run = result instanceof Promise ? runAsync(runRaw) : runSync(runRaw);\n const start = Date.now();\n while (Date.now() - start < 1_000) {\n Math.sqrt(Math.random());\n }\n for (let i = 0; i < warmupCycles; i++) {\n await pre?.(context, data!);\n await run(context, data);\n await post?.(context, data!);\n }\n\n let i = 0;\n let mean = 0n;\n let m2 = 0n;\n\n while (true) {\n if (i >= maxCycles) break;\n\n await pre?.(context, data!);\n const duration = await run(context, data);\n await post?.(context, data!);\n\n durations[i++] = duration;\n const delta = duration - mean;\n mean += delta / BigInt(i);\n m2 += delta * (duration - mean);\n\n const progress = Math.max(i / maxCycles) * COMPLETE_VALUE;\n control[Control.PROGRESS] = progress;\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 } catch (e) {\n console.error(e && typeof e === 'object' && 'stack' in e ? e.stack : e);\n control[Control.COMPLETE] = 1;\n } finally {\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":["Control","COMPLETE_VALUE","runSync","run","args","start","process","hrtime","bigint","runAsync","benchmark","setup","teardown","pre","runRaw","post","data","warmupCycles","minCycles","absThreshold","relThreshold","durationsSAB","controlSAB","durations","BigUint64Array","control","Int32Array","INDEX","PROGRESS","COMPLETE","context","maxCycles","length","result","Promise","Date","now","Math","sqrt","random","i","mean","m2","duration","delta","BigInt","progress","max","variance","Number","stddev","meanNum","cov","e","console","error","stack"],"mappings":"AAAA,SAAkBA,OAAO,QAAQ,aAAa;AAE9C,MAAMC,iBAAiB;AAEvB,MAAMC,UAAU,CAACC;IACf,OAAO,CAAC,GAAGC;QACT,MAAMC,QAAQC,QAAQC,MAAM,CAACC,MAAM;QACnCL,OAAOC;QACP,OAAOE,QAAQC,MAAM,CAACC,MAAM,KAAKH;IACnC;AACF;AAEA,MAAMI,WAAW,CAACN;IAChB,OAAO,OAAO,GAAGC;QACf,MAAMC,QAAQC,QAAQC,MAAM,CAACC,MAAM;QACnC,MAAML,OAAOC;QACb,OAAOE,QAAQC,MAAM,CAACC,MAAM,KAAKH;IACnC;AACF;AAEA,OAAO,MAAMK,YAAY,OAAyB,EAChDC,KAAK,EACLC,QAAQ,EACRC,GAAG,EACHV,KAAKW,MAAM,EACXC,IAAI,EACJC,IAAI,EAEJC,YAAY,EACZC,SAAS,EACTC,YAAY,EACZC,YAAY,EAEZC,YAAY,EACZC,UAAU,EAC0B;IACpC,MAAMC,YAAY,IAAIC,eAAeH;IACrC,MAAMI,UAAU,IAAIC,WAAWJ;IAE/BG,OAAO,CAACzB,QAAQ2B,KAAK,CAAC,GAAG;IACzBF,OAAO,CAACzB,QAAQ4B,QAAQ,CAAC,GAAG;IAC5BH,OAAO,CAACzB,QAAQ6B,QAAQ,CAAC,GAAG;IAE5B,MAAMC,UAAW,MAAMnB;IACvB,MAAMoB,YAAYR,UAAUS,MAAM;IAElC,IAAI;QACF,MAAMnB,MAAMiB,SAASd;QACrB,MAAMiB,SAASnB,OAAOgB,SAASd;QAC/B,MAAMD,OAAOe,SAASd;QACtB,MAAMb,MAAM8B,kBAAkBC,UAAUzB,SAASK,UAAUZ,QAAQY;QACnE,MAAMT,QAAQ8B,KAAKC,GAAG;QACtB,MAAOD,KAAKC,GAAG,KAAK/B,QAAQ,MAAO;YACjCgC,KAAKC,IAAI,CAACD,KAAKE,MAAM;QACvB;QACA,IAAK,IAAIC,IAAI,GAAGA,IAAIvB,cAAcuB,IAAK;YACrC,MAAM3B,MAAMiB,SAASd;YACrB,MAAMb,IAAI2B,SAASd;YACnB,MAAMD,OAAOe,SAASd;QACxB;QAEA,IAAIwB,IAAI;QACR,IAAIC,OAAO,EAAE;QACb,IAAIC,KAAK,EAAE;QAEX,MAAO,KAAM;YACX,IAAIF,KAAKT,WAAW;YAEpB,MAAMlB,MAAMiB,SAASd;YACrB,MAAM2B,WAAW,MAAMxC,IAAI2B,SAASd;YACpC,MAAMD,OAAOe,SAASd;YAEtBO,SAAS,CAACiB,IAAI,GAAGG;YACjB,MAAMC,QAAQD,WAAWF;YACzBA,QAAQG,QAAQC,OAAOL;YACvBE,MAAME,QAASD,CAAAA,WAAWF,IAAG;YAE7B,MAAMK,WAAWT,KAAKU,GAAG,CAACP,IAAIT,aAAa9B;YAC3CwB,OAAO,CAACzB,QAAQ4B,QAAQ,CAAC,GAAGkB;YAE5B,IAAIN,KAAKtB,WAAW;gBAClB,MAAM8B,WAAWC,OAAOP,MAAOF,CAAAA,IAAI,CAAA;gBACnC,MAAMU,SAASb,KAAKC,IAAI,CAACU;gBACzB,IAAIE,UAAUD,OAAO9B,eAAe;oBAClC;gBACF;gBAEA,MAAMgC,UAAUF,OAAOR;gBACvB,MAAMW,MAAMF,SAAUC,CAAAA,WAAW,CAAA;gBACjC,IAAIC,OAAOhC,cAAc;oBACvB;gBACF;YACF;QACF;QAEAK,OAAO,CAACzB,QAAQ2B,KAAK,CAAC,GAAGa;QACzBf,OAAO,CAACzB,QAAQ6B,QAAQ,CAAC,GAAG;IAC9B,EAAE,OAAOwB,GAAG;QACVC,QAAQC,KAAK,CAACF,KAAK,OAAOA,MAAM,YAAY,WAAWA,IAAIA,EAAEG,KAAK,GAAGH;QACrE5B,OAAO,CAACzB,QAAQ6B,QAAQ,CAAC,GAAG;IAC9B,SAAU;QACR,IAAI;YACF,MAAMjB,WAAWkB;QACnB,EAAE,OAAOuB,GAAG;YACV5B,OAAO,CAACzB,QAAQ6B,QAAQ,CAAC,GAAG;YAC5ByB,QAAQC,KAAK,CAACF,KAAK,OAAOA,MAAM,YAAY,WAAWA,IAAIA,EAAEG,KAAK,GAAGH;QACvE;IACF;IAEA,OAAO5B,OAAO,CAACzB,QAAQ6B,QAAQ,CAAC;AAClC,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../src/runner.ts"],"sourcesContent":["import { performance, PerformanceObserver } from 'node:perf_hooks';\nimport { Options, Control } from './types.js';\nimport { GCWatcher } from './gc-watcher.js';\nimport { StepFn, MaybePromise } from './types.js';\n\nconst COMPLETE_VALUE = 100_00;\n\nconst hr = process.hrtime.bigint.bind(process.hrtime);\n\nconst runSync = (run: Function) => {\n return (...args: unknown[]) => {\n const start = hr();\n run(...args);\n return hr() - start;\n };\n};\n\nconst runAsync = (run: Function) => {\n return async (...args: unknown[]) => {\n const start = hr();\n await run(...args);\n return hr() - start;\n };\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;\n\ntype GCEvent = { start: number; end: number };\n\nconst collectSample = async <TContext, TInput>(\n batchSize: number,\n run: (ctx: TContext, data: TInput) => MaybePromise<bigint>,\n pre: StepFn<TContext, TInput> | undefined,\n post: StepFn<TContext, TInput> | undefined,\n context: TContext,\n data: TInput,\n) => {\n let sampleDuration = 0n;\n for (let b = 0; b < batchSize; b++) {\n await pre?.(context, data);\n sampleDuration += await run(context, data);\n await post?.(context, data);\n }\n return sampleDuration / BigInt(batchSize);\n};\n\nconst tuneParameters = async <TContext, TInput>({\n initialBatch,\n run,\n pre,\n post,\n context,\n data,\n minCycles,\n relThreshold,\n maxCycles,\n}: {\n initialBatch: number;\n run: (ctx: TContext, data: TInput) => MaybePromise<bigint>;\n pre?: StepFn<TContext, TInput>;\n post?: StepFn<TContext, TInput>;\n context: TContext;\n data: TInput;\n minCycles: number;\n relThreshold: number;\n maxCycles: number;\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(batchSize, run, pre, post, context, data);\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 const sorted = [...arr].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n const median = sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];\n const q1Idx = Math.floor(sorted.length * 0.25);\n const q3Idx = Math.floor(sorted.length * 0.75);\n const q1 = sorted[q1Idx];\n const q3 = sorted[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\n const context = (await setup?.()) as TContext;\n const maxCycles = durations.length;\n const gcWatcher = new GCWatcher();\n const gcTracker = gcObserver ? createGCTracker() : null;\n\n try {\n // classify sync/async and capture initial duration\n await pre?.(context, data!);\n const probeStart = hr();\n const probeResult = runRaw(context, data!);\n const isAsync = probeResult instanceof Promise;\n if (isAsync) {\n await probeResult;\n }\n const durationProbe = hr() - probeStart;\n await post?.(context, data!);\n\n const run = isAsync ? runAsync(runRaw) : runSync(runRaw);\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 initialBatchSize = Math.min(MAX_BATCH, Math.max(1, suggestedBatch));\n\n // auto-tune based on warmup samples\n const tuned = await tuneParameters({\n initialBatch: initialBatchSize,\n run,\n pre,\n post,\n context,\n data: data as TInput,\n minCycles,\n relThreshold,\n maxCycles,\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 = Date.now();\n let warmupRemaining = warmupCycles;\n const warmupWindow: number[] = [];\n const warmupCap = Math.max(warmupCycles, Math.min(maxCycles, warmupCycles * 4 || 1000));\n\n while (Date.now() - warmupStart < 1_000 && warmupRemaining > 0) {\n const start = hr();\n await pre?.(context, data!);\n await run(context, data);\n await post?.(context, data!);\n pushWindow(warmupWindow, Number(hr() - start), warmupCap);\n warmupRemaining--;\n }\n let warmupDone = 0;\n while (warmupDone < warmupRemaining) {\n const start = hr();\n await pre?.(context, data!);\n await run(context, data);\n await post?.(context, data!);\n pushWindow(warmupWindow, Number(hr() - start), 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 start = hr();\n await pre?.(context, data!);\n await run(context, data);\n await post?.(context, data!);\n pushWindow(warmupWindow, Number(hr() - start), warmupCap);\n }\n\n let i = 0;\n let mean = 0n;\n let m2 = 0n;\n const outlierWindow: number[] = [];\n\n while (true) {\n if (i >= maxCycles) break;\n\n const gcMarker = gcWatcher.start();\n const sampleStart = performance.now();\n let sampleDuration = 0n;\n for (let b = 0; b < batchSize; b++) {\n await pre?.(context, data!);\n sampleDuration += await run(context, data);\n await post?.(context, data!);\n if (global.gc && (i + b) % GC_STRIDE === 0) {\n global.gc();\n }\n }\n\n // normalize by batch size\n sampleDuration /= BigInt(batchSize);\n\n const sampleEnd = performance.now();\n const gcNoise = gcWatcher.seen(gcMarker) || (gcTracker?.overlaps(sampleStart, sampleEnd) ?? false);\n if (gcNoise) {\n continue;\n }\n\n const durationNumber = Number(sampleDuration);\n pushWindow(outlierWindow, durationNumber, OUTLIER_WINDOW);\n const { median, iqr } = medianAndIqr(outlierWindow);\n const maxAllowed = median + OUTLIER_IQR_MULTIPLIER * iqr || Number.POSITIVE_INFINITY;\n if (outlierWindow.length >= 8 && durationNumber > maxAllowed) {\n continue;\n }\n\n const meanNumber = Number(mean);\n if (i >= 8 && meanNumber > 0 && durationNumber > OUTLIER_MULTIPLIER * meanNumber) {\n continue;\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 = Math.max(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 } 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","GCWatcher","COMPLETE_VALUE","hr","process","hrtime","bigint","bind","runSync","run","args","start","runAsync","TARGET_SAMPLE_NS","MAX_BATCH","PROGRESS_STRIDE","GC_STRIDE","OUTLIER_MULTIPLIER","OUTLIER_IQR_MULTIPLIER","OUTLIER_WINDOW","collectSample","batchSize","pre","post","context","data","sampleDuration","b","BigInt","tuneParameters","initialBatch","minCycles","relThreshold","maxCycles","bestCv","Number","POSITIVE_INFINITY","bestBatch","attempt","samples","sampleCount","Math","min","s","duration","push","mean","reduce","acc","v","length","variance","max","stddev","sqrt","cv","tunedRel","tunedMin","ceil","createGCTracker","env","OVERTAKE_GC_OBSERVER","events","observer","list","entry","getEntries","startTime","end","observe","entryTypes","overlaps","noisy","i","event","splice","dispose","disconnect","pushWindow","arr","value","cap","shift","medianAndIqr","median","iqr","sorted","sort","a","mid","floor","q1Idx","q3Idx","q1","q3","windowCv","benchmark","setup","teardown","runRaw","warmupCycles","absThreshold","gcObserver","durationsSAB","controlSAB","durations","BigUint64Array","control","Int32Array","INDEX","PROGRESS","COMPLETE","gcWatcher","gcTracker","probeStart","probeResult","isAsync","Promise","durationProbe","durationPerRun","suggestedBatch","initialBatchSize","tuned","warmupStart","Date","now","warmupRemaining","warmupWindow","warmupCap","warmupDone","global","gc","m2","outlierWindow","gcMarker","sampleStart","sampleEnd","gcNoise","seen","durationNumber","maxAllowed","meanNumber","delta","progress","meanNum","cov","e","console","error","stack"],"mappings":"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"}
|
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<void>;\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 = 'ops' | 'min' | 'max' | 'mean' | 'median' | 'mode' | `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(['ops', 'mean', 'min', 'max', 'median', 'mode']);\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}\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 WorkerOptions extends Required<BenchmarkOptions> {\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}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 1_000;\nexport const Z95 = 1.96;\n"],"names":["CONTROL_SLOTS","Control","DEFAULT_CYCLES","REPORT_TYPES","Z95","Array","from","length","_","idx","concat","Object","values"],"mappings":";;;;;;;;;;;
|
|
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<void>;\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 = 'ops' | 'min' | 'max' | 'mean' | 'median' | 'mode' | `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(['ops', 'mean', 'min', 'max', 'median', 'mode']);\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 baseUrl?: string;\n}\n\nexport interface RunOptions<TContext, TInput> {\n baseUrl?: string;\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 WorkerOptions extends Required<BenchmarkOptions> {\n baseUrl: 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}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 1_000;\nexport const Z95 = 1.96;\n"],"names":["CONTROL_SLOTS","Control","DEFAULT_CYCLES","REPORT_TYPES","Z95","Array","from","length","_","idx","concat","Object","values"],"mappings":";;;;;;;;;;;QAyEaA;eAAAA;;QANDC;eAAAA;;QAOCC;eAAAA;;QAlDAC;eAAAA;;QAmDAC;eAAAA;;;AAnDN,MAAMD,eAA+BE,MAAMC,IAAI,CAAC;IAAEC,QAAQ;AAAG,GAAG,CAACC,GAAGC,MAAQ,CAAC,CAAC,EAAEA,MAAM,GAAG,EAAgBC,MAAM,CAAC;IAAC;IAAO;IAAQ;IAAO;IAAO;IAAU;CAAO;AA2C/J,IAAA,AAAKT,iCAAAA;;;;WAAAA;;AAML,MAAMD,gBAAgBW,OAAOC,MAAM,CAACX,SAASM,MAAM,GAAG;AACtD,MAAML,iBAAiB;AACvB,MAAME,MAAM"}
|
package/build/types.d.ts
CHANGED
|
@@ -25,8 +25,11 @@ export interface BenchmarkOptions {
|
|
|
25
25
|
minCycles?: number;
|
|
26
26
|
absThreshold?: number;
|
|
27
27
|
relThreshold?: number;
|
|
28
|
+
gcObserver?: boolean;
|
|
29
|
+
baseUrl?: string;
|
|
28
30
|
}
|
|
29
31
|
export interface RunOptions<TContext, TInput> {
|
|
32
|
+
baseUrl?: string;
|
|
30
33
|
setup?: SetupFn<TContext>;
|
|
31
34
|
teardown?: TeardownFn<TContext>;
|
|
32
35
|
pre?: StepFn<TContext, TInput>;
|
|
@@ -35,6 +38,7 @@ export interface RunOptions<TContext, TInput> {
|
|
|
35
38
|
data?: TInput;
|
|
36
39
|
}
|
|
37
40
|
export interface WorkerOptions extends Required<BenchmarkOptions> {
|
|
41
|
+
baseUrl: string;
|
|
38
42
|
setupCode?: string;
|
|
39
43
|
teardownCode?: string;
|
|
40
44
|
preCode?: string;
|
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<void>;\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 = 'ops' | 'min' | 'max' | 'mean' | 'median' | 'mode' | `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(['ops', 'mean', 'min', 'max', 'median', 'mode']);\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}\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 WorkerOptions extends Required<BenchmarkOptions> {\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}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 1_000;\nexport const Z95 = 1.96;\n"],"names":["REPORT_TYPES","Array","from","length","_","idx","concat","Control","CONTROL_SLOTS","Object","values","DEFAULT_CYCLES","Z95"],"mappings":"AAwBA,OAAO,MAAMA,eAA+BC,MAAMC,IAAI,CAAC;IAAEC,QAAQ;AAAG,GAAG,CAACC,GAAGC,MAAQ,CAAC,CAAC,EAAEA,MAAM,GAAG,EAAgBC,MAAM,CAAC;IAAC;IAAO;IAAQ;IAAO;IAAO;IAAU;CAAO,EAAE;
|
|
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<void>;\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 = 'ops' | 'min' | 'max' | 'mean' | 'median' | 'mode' | `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(['ops', 'mean', 'min', 'max', 'median', 'mode']);\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 baseUrl?: string;\n}\n\nexport interface RunOptions<TContext, TInput> {\n baseUrl?: string;\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 WorkerOptions extends Required<BenchmarkOptions> {\n baseUrl: 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}\n\nexport const CONTROL_SLOTS = Object.values(Control).length / 2;\nexport const DEFAULT_CYCLES = 1_000;\nexport const Z95 = 1.96;\n"],"names":["REPORT_TYPES","Array","from","length","_","idx","concat","Control","CONTROL_SLOTS","Object","values","DEFAULT_CYCLES","Z95"],"mappings":"AAwBA,OAAO,MAAMA,eAA+BC,MAAMC,IAAI,CAAC;IAAEC,QAAQ;AAAG,GAAG,CAACC,GAAGC,MAAQ,CAAC,CAAC,EAAEA,MAAM,GAAG,EAAgBC,MAAM,CAAC;IAAC;IAAO;IAAQ;IAAO;IAAO;IAAU;CAAO,EAAE;AA2CxK,OAAO,IAAA,AAAKC,iCAAAA;;;;WAAAA;MAIX;AAED,OAAO,MAAMC,gBAAgBC,OAAOC,MAAM,CAACH,SAASJ,MAAM,GAAG,EAAE;AAC/D,OAAO,MAAMQ,iBAAiB,MAAM;AACpC,OAAO,MAAMC,MAAM,KAAK"}
|
package/build/utils.cjs
CHANGED
|
@@ -29,8 +29,12 @@ _export(exports, {
|
|
|
29
29
|
},
|
|
30
30
|
get max () {
|
|
31
31
|
return max;
|
|
32
|
+
},
|
|
33
|
+
get transpile () {
|
|
34
|
+
return transpile;
|
|
32
35
|
}
|
|
33
36
|
});
|
|
37
|
+
const _core = require("@swc/core");
|
|
34
38
|
const abs = (value)=>{
|
|
35
39
|
if (value < 0n) {
|
|
36
40
|
return -value;
|
|
@@ -96,5 +100,22 @@ class ScaledBigInt {
|
|
|
96
100
|
return Number(div(this.value, this.scale));
|
|
97
101
|
}
|
|
98
102
|
}
|
|
103
|
+
const transpile = async (code)=>{
|
|
104
|
+
const output = await (0, _core.transform)(code, {
|
|
105
|
+
filename: 'benchmark.ts',
|
|
106
|
+
jsc: {
|
|
107
|
+
parser: {
|
|
108
|
+
syntax: 'typescript',
|
|
109
|
+
tsx: false,
|
|
110
|
+
dynamicImport: true
|
|
111
|
+
},
|
|
112
|
+
target: 'esnext'
|
|
113
|
+
},
|
|
114
|
+
module: {
|
|
115
|
+
type: 'es6'
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return output.code;
|
|
119
|
+
};
|
|
99
120
|
|
|
100
121
|
//# sourceMappingURL=utils.cjs.map
|
package/build/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["
|
|
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","RangeError","scale","BigInt","scaled","intPart","fracPart","toString","padStart","add","sub","mul","unscale","number","Number","code","output","transform","filename","jsc","parser","syntax","tsx","dynamicImport","target","module","type"],"mappings":";;;;;;;;;;;QA2CaA;eAAAA;;QAzCAC;eAAAA;;QAMAC;eAAAA;;QAqBGC;eAAAA;;QAJHC;eAAAA;;QAaGC;eAAAA;;QApBHC;eAAAA;;QAkDAC;eAAAA;;;sBApEa;AAEnB,MAAMN,MAAM,CAACO;IAClB,IAAIA,QAAQ,EAAE,EAAE;QACd,OAAO,CAACA;IACV;IACA,OAAOA;AACT;AACO,MAAMN,MAAM,CAACO,GAAoBC;IACtC,IAAID,IAAIC,GAAG;QACT,OAAO;IACT;IACA,IAAID,IAAIC,GAAG;QACT,OAAO,CAAC;IACV;IACA,OAAO;AACT;AAEO,MAAMJ,MAAM,CAACG,GAAWC;IAC7B,IAAID,IAAIC,GAAG;QACT,OAAOD;IACT;IACA,OAAOC;AACT;AAEO,MAAMN,SAAS,CAACK,GAAWC;IAChC,OAAO;QAAEC,UAAUF,IAAIC;QAAGE,WAAWH,IAAIC;IAAE;AAC7C;AAEO,SAASP,IAAIM,CAAS,EAAEC,CAAS,EAAEG,WAAmB,CAAC;IAC5D,IAAIH,MAAM,EAAE,EAAE,MAAM,IAAII,WAAW;IACnC,MAAMC,QAAQ,GAAG,IAAIC,OAAOH;IAC5B,MAAMI,SAAS,AAACR,IAAIM,QAASL;IAC7B,MAAMQ,UAAUD,SAASF;IACzB,MAAMI,WAAWF,SAASF;IAC1B,OAAO,GAAGG,QAAQ,CAAC,EAAEC,SAASC,QAAQ,GAAGC,QAAQ,CAACR,UAAU,MAAM;AACpE;AAEO,SAASR,KAAKI,CAAS,EAAEC,CAAS,EAAEK,KAAa;IACtD,IAAIL,MAAM,EAAE,EAAE,MAAM,IAAII,WAAW;IACnC,OAAO,AAACL,IAAIM,QAASL;AACvB;AAEO,MAAMV;;;IACX,YACE,AAAOQ,KAAa,EACpB,AAAOO,KAAa,CACpB;aAFOP,QAAAA;aACAO,QAAAA;IACN;IACHO,IAAId,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACO,KAAK;IAClC;IACAQ,IAAIf,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACO,KAAK;IAClC;IACAZ,IAAIK,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAgB,IAAIhB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAiB,UAAU;QACR,OAAO,IAAI,CAACjB,KAAK,GAAG,IAAI,CAACO,KAAK;IAChC;IACAW,SAAS;QACP,OAAOC,OAAOxB,IAAI,IAAI,CAACK,KAAK,EAAE,IAAI,CAACO,KAAK;IAC1C;AACF;AAEO,MAAMR,YAAY,OAAOqB;IAC9B,MAAMC,SAAS,MAAMC,IAAAA,eAAS,EAACF,MAAM;QACnCG,UAAU;QACVC,KAAK;YACHC,QAAQ;gBACNC,QAAQ;gBACRC,KAAK;gBACLC,eAAe;YACjB;YACAC,QAAQ;QACV;QACAC,QAAQ;YACNC,MAAM;QACR;IACF;IACA,OAAOV,OAAOD,IAAI;AACpB"}
|
package/build/utils.d.ts
CHANGED
package/build/utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { transform } from '@swc/core';
|
|
1
2
|
export const abs = (value)=>{
|
|
2
3
|
if (value < 0n) {
|
|
3
4
|
return -value;
|
|
@@ -63,5 +64,22 @@ export class ScaledBigInt {
|
|
|
63
64
|
return Number(div(this.value, this.scale));
|
|
64
65
|
}
|
|
65
66
|
}
|
|
67
|
+
export const transpile = async (code)=>{
|
|
68
|
+
const output = await transform(code, {
|
|
69
|
+
filename: 'benchmark.ts',
|
|
70
|
+
jsc: {
|
|
71
|
+
parser: {
|
|
72
|
+
syntax: 'typescript',
|
|
73
|
+
tsx: false,
|
|
74
|
+
dynamicImport: true
|
|
75
|
+
},
|
|
76
|
+
target: 'esnext'
|
|
77
|
+
},
|
|
78
|
+
module: {
|
|
79
|
+
type: 'es6'
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return output.code;
|
|
83
|
+
};
|
|
66
84
|
|
|
67
85
|
//# sourceMappingURL=utils.js.map
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["
|
|
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","RangeError","scale","BigInt","scaled","intPart","fracPart","toString","padStart","divs","ScaledBigInt","add","sub","mul","unscale","number","Number","transpile","code","output","filename","jsc","parser","syntax","tsx","dynamicImport","target","module","type"],"mappings":"AAAA,SAASA,SAAS,QAAQ,YAAY;AAEtC,OAAO,MAAMC,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,IAAIO,WAAW;IACnC,MAAMC,QAAQ,GAAG,IAAIC,OAAOH;IAC5B,MAAMI,SAAS,AAACX,IAAIS,QAASR;IAC7B,MAAMW,UAAUD,SAASF;IACzB,MAAMI,WAAWF,SAASF;IAC1B,OAAO,GAAGG,QAAQ,CAAC,EAAEC,SAASC,QAAQ,GAAGC,QAAQ,CAACR,UAAU,MAAM;AACpE;AAEA,OAAO,SAASS,KAAKhB,CAAS,EAAEC,CAAS,EAAEQ,KAAa;IACtD,IAAIR,MAAM,EAAE,EAAE,MAAM,IAAIO,WAAW;IACnC,OAAO,AAACR,IAAIS,QAASR;AACvB;AAEA,OAAO,MAAMgB;;;IACX,YACE,AAAOnB,KAAa,EACpB,AAAOW,KAAa,CACpB;aAFOX,QAAAA;aACAW,QAAAA;IACN;IACHS,IAAIpB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACW,KAAK;IAClC;IACAU,IAAIrB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA,QAAQ,IAAI,CAACW,KAAK;IAClC;IACAH,IAAIR,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAsB,IAAItB,KAAa,EAAE;QACjB,IAAI,CAACA,KAAK,IAAIA;IAChB;IACAuB,UAAU;QACR,OAAO,IAAI,CAACvB,KAAK,GAAG,IAAI,CAACW,KAAK;IAChC;IACAa,SAAS;QACP,OAAOC,OAAOjB,IAAI,IAAI,CAACR,KAAK,EAAE,IAAI,CAACW,KAAK;IAC1C;AACF;AAEA,OAAO,MAAMe,YAAY,OAAOC;IAC9B,MAAMC,SAAS,MAAM9B,UAAU6B,MAAM;QACnCE,UAAU;QACVC,KAAK;YACHC,QAAQ;gBACNC,QAAQ;gBACRC,KAAK;gBACLC,eAAe;YACjB;YACAC,QAAQ;QACV;QACAC,QAAQ;YACNC,MAAM;QACR;IACF;IACA,OAAOT,OAAOD,IAAI;AACpB,EAAE"}
|
package/build/worker.cjs
CHANGED
|
@@ -3,14 +3,101 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
const _nodeworker_threads = require("node:worker_threads");
|
|
6
|
+
const _nodevm = require("node:vm");
|
|
7
|
+
const _nodemodule = require("node:module");
|
|
8
|
+
const _nodeurl = require("node:url");
|
|
6
9
|
const _runnercjs = require("./runner.cjs");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
11
|
+
if (typeof WeakMap !== "function") return null;
|
|
12
|
+
var cacheBabelInterop = new WeakMap();
|
|
13
|
+
var cacheNodeInterop = new WeakMap();
|
|
14
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
15
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
16
|
+
})(nodeInterop);
|
|
17
|
+
}
|
|
18
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
19
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
23
|
+
return {
|
|
24
|
+
default: obj
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
28
|
+
if (cache && cache.has(obj)) {
|
|
29
|
+
return cache.get(obj);
|
|
30
|
+
}
|
|
31
|
+
var newObj = {
|
|
32
|
+
__proto__: null
|
|
33
|
+
};
|
|
34
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
35
|
+
for(var key in obj){
|
|
36
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
37
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
38
|
+
if (desc && (desc.get || desc.set)) {
|
|
39
|
+
Object.defineProperty(newObj, key, desc);
|
|
40
|
+
} else {
|
|
41
|
+
newObj[key] = obj[key];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
newObj.default = obj;
|
|
46
|
+
if (cache) {
|
|
47
|
+
cache.set(obj, newObj);
|
|
48
|
+
}
|
|
49
|
+
return newObj;
|
|
50
|
+
}
|
|
51
|
+
const { baseUrl, setupCode, teardownCode, preCode, runCode, postCode, data, warmupCycles, minCycles, absThreshold, relThreshold, gcObserver = true, durationsSAB, controlSAB } = _nodeworker_threads.workerData;
|
|
52
|
+
const serialize = (code)=>code ? code : '() => {}';
|
|
53
|
+
const source = `
|
|
54
|
+
export const setup = ${serialize(setupCode)};
|
|
55
|
+
export const teardown = ${serialize(teardownCode)};
|
|
56
|
+
export const pre = ${serialize(preCode)};
|
|
57
|
+
export const run = ${serialize(runCode)};
|
|
58
|
+
export const post = ${serialize(postCode)};
|
|
59
|
+
`;
|
|
60
|
+
const context = (0, _nodevm.createContext)({
|
|
61
|
+
console,
|
|
62
|
+
Buffer
|
|
63
|
+
});
|
|
64
|
+
const imports = new Map();
|
|
65
|
+
const mod = new _nodevm.SourceTextModule(source, {
|
|
66
|
+
identifier: baseUrl,
|
|
67
|
+
context,
|
|
68
|
+
initializeImportMeta (meta) {
|
|
69
|
+
meta.url = baseUrl;
|
|
70
|
+
},
|
|
71
|
+
importModuleDynamically (specifier, referencingModule) {
|
|
72
|
+
const base = referencingModule.identifier ?? baseUrl;
|
|
73
|
+
const resolveFrom = (0, _nodemodule.createRequire)((0, _nodeurl.fileURLToPath)(base));
|
|
74
|
+
return Promise.resolve(resolveFrom.resolve(specifier)).then((p)=>/*#__PURE__*/ _interop_require_wildcard(require(p)));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
await mod.link(async (specifier, referencingModule)=>{
|
|
78
|
+
const base = referencingModule.identifier ?? baseUrl;
|
|
79
|
+
const resolveFrom = (0, _nodemodule.createRequire)((0, _nodeurl.fileURLToPath)(base));
|
|
80
|
+
const target = resolveFrom.resolve(specifier);
|
|
81
|
+
const cached = imports.get(target);
|
|
82
|
+
if (cached) return cached;
|
|
83
|
+
const importedModule = await Promise.resolve(target).then((p)=>/*#__PURE__*/ _interop_require_wildcard(require(p)));
|
|
84
|
+
const exportNames = Object.keys(importedModule);
|
|
85
|
+
const imported = new _nodevm.SyntheticModule(exportNames, ()=>{
|
|
86
|
+
exportNames.forEach((key)=>imported.setExport(key, importedModule[key]));
|
|
87
|
+
}, {
|
|
88
|
+
identifier: target,
|
|
89
|
+
context: referencingModule.context
|
|
90
|
+
});
|
|
91
|
+
imports.set(target, imported);
|
|
92
|
+
return imported;
|
|
93
|
+
});
|
|
94
|
+
await mod.evaluate();
|
|
95
|
+
const { setup, teardown, pre, run, post } = mod.namespace;
|
|
96
|
+
if (!run) {
|
|
97
|
+
throw new Error('Benchmark run function is required');
|
|
98
|
+
}
|
|
99
|
+
process.exitCode = await (0, _runnercjs.benchmark)({
|
|
100
|
+
baseUrl,
|
|
14
101
|
setup,
|
|
15
102
|
teardown,
|
|
16
103
|
pre,
|
|
@@ -21,9 +108,9 @@ const exitCode = await (0, _runnercjs.benchmark)({
|
|
|
21
108
|
minCycles,
|
|
22
109
|
absThreshold,
|
|
23
110
|
relThreshold,
|
|
111
|
+
gcObserver,
|
|
24
112
|
durationsSAB,
|
|
25
113
|
controlSAB
|
|
26
114
|
});
|
|
27
|
-
process.exit(exitCode);
|
|
28
115
|
|
|
29
116
|
//# sourceMappingURL=worker.cjs.map
|
package/build/worker.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport { benchmark } from './runner.js';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport { SourceTextModule, SyntheticModule, createContext } from 'node:vm';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport { benchmark } from './runner.js';\nimport { WorkerOptions } from './types.js';\n\nconst {\n baseUrl,\n setupCode,\n teardownCode,\n preCode,\n runCode,\n postCode,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver = true,\n\n durationsSAB,\n controlSAB,\n}: WorkerOptions = workerData;\n\nconst serialize = (code?: string) => (code ? code : '() => {}');\n\nconst source = `\nexport const setup = ${serialize(setupCode)};\nexport const teardown = ${serialize(teardownCode)};\nexport const pre = ${serialize(preCode)};\nexport const run = ${serialize(runCode)};\nexport const post = ${serialize(postCode)};\n `;\n\nconst context = createContext({ console, Buffer });\nconst imports = new Map<string, SyntheticModule>();\nconst mod = new SourceTextModule(source, {\n identifier: baseUrl,\n context,\n initializeImportMeta(meta) {\n meta.url = baseUrl;\n },\n importModuleDynamically(specifier, referencingModule) {\n const base = referencingModule.identifier ?? baseUrl;\n const resolveFrom = createRequire(fileURLToPath(base));\n return import(resolveFrom.resolve(specifier));\n },\n});\n\nawait mod.link(async (specifier, referencingModule) => {\n const base = referencingModule.identifier ?? baseUrl;\n const resolveFrom = createRequire(fileURLToPath(base));\n const target = resolveFrom.resolve(specifier);\n const cached = imports.get(target);\n if (cached) return cached;\n\n const importedModule = await import(target);\n const exportNames = Object.keys(importedModule);\n const imported = new SyntheticModule(\n exportNames,\n () => {\n exportNames.forEach((key) => imported.setExport(key, importedModule[key]));\n },\n { identifier: target, context: referencingModule.context },\n );\n imports.set(target, imported);\n return imported;\n});\n\nawait mod.evaluate();\nconst { setup, teardown, pre, run, post } = mod.namespace as any;\n\nif (!run) {\n throw new Error('Benchmark run function is required');\n}\n\nprocess.exitCode = await benchmark({\n baseUrl,\n setup,\n teardown,\n pre,\n run,\n post,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver,\n\n durationsSAB,\n controlSAB,\n});\n"],"names":["baseUrl","setupCode","teardownCode","preCode","runCode","postCode","data","warmupCycles","minCycles","absThreshold","relThreshold","gcObserver","durationsSAB","controlSAB","workerData","serialize","code","source","context","createContext","console","Buffer","imports","Map","mod","SourceTextModule","identifier","initializeImportMeta","meta","url","importModuleDynamically","specifier","referencingModule","base","resolveFrom","createRequire","fileURLToPath","resolve","link","target","cached","get","importedModule","exportNames","Object","keys","imported","SyntheticModule","forEach","key","setExport","set","evaluate","setup","teardown","pre","run","post","namespace","Error","process","exitCode","benchmark"],"mappings":";;;;oCAA2B;wBACsC;4BACnC;yBACA;2BACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG1B,MAAM,EACJA,OAAO,EACPC,SAAS,EACTC,YAAY,EACZC,OAAO,EACPC,OAAO,EACPC,QAAQ,EACRC,IAAI,EAEJC,YAAY,EACZC,SAAS,EACTC,YAAY,EACZC,YAAY,EACZC,aAAa,IAAI,EAEjBC,YAAY,EACZC,UAAU,EACX,GAAkBC,8BAAU;AAE7B,MAAMC,YAAY,CAACC,OAAmBA,OAAOA,OAAO;AAEpD,MAAMC,SAAS,CAAC;qBACK,EAAEF,UAAUd,WAAW;wBACpB,EAAEc,UAAUb,cAAc;mBAC/B,EAAEa,UAAUZ,SAAS;mBACrB,EAAEY,UAAUX,SAAS;oBACpB,EAAEW,UAAUV,UAAU;EACxC,CAAC;AAEH,MAAMa,UAAUC,IAAAA,qBAAa,EAAC;IAAEC;IAASC;AAAO;AAChD,MAAMC,UAAU,IAAIC;AACpB,MAAMC,MAAM,IAAIC,wBAAgB,CAACR,QAAQ;IACvCS,YAAY1B;IACZkB;IACAS,sBAAqBC,IAAI;QACvBA,KAAKC,GAAG,GAAG7B;IACb;IACA8B,yBAAwBC,SAAS,EAAEC,iBAAiB;QAClD,MAAMC,OAAOD,kBAAkBN,UAAU,IAAI1B;QAC7C,MAAMkC,cAAcC,IAAAA,yBAAa,EAACC,IAAAA,sBAAa,EAACH;QAChD,OAAO,gBAAOC,YAAYG,OAAO,CAACN,8DAA3B;IACT;AACF;AAEA,MAAMP,IAAIc,IAAI,CAAC,OAAOP,WAAWC;IAC/B,MAAMC,OAAOD,kBAAkBN,UAAU,IAAI1B;IAC7C,MAAMkC,cAAcC,IAAAA,yBAAa,EAACC,IAAAA,sBAAa,EAACH;IAChD,MAAMM,SAASL,YAAYG,OAAO,CAACN;IACnC,MAAMS,SAASlB,QAAQmB,GAAG,CAACF;IAC3B,IAAIC,QAAQ,OAAOA;IAEnB,MAAME,iBAAiB,MAAM,gBAAOH,0DAAP;IAC7B,MAAMI,cAAcC,OAAOC,IAAI,CAACH;IAChC,MAAMI,WAAW,IAAIC,uBAAe,CAClCJ,aACA;QACEA,YAAYK,OAAO,CAAC,CAACC,MAAQH,SAASI,SAAS,CAACD,KAAKP,cAAc,CAACO,IAAI;IAC1E,GACA;QAAEvB,YAAYa;QAAQrB,SAASc,kBAAkBd,OAAO;IAAC;IAE3DI,QAAQ6B,GAAG,CAACZ,QAAQO;IACpB,OAAOA;AACT;AAEA,MAAMtB,IAAI4B,QAAQ;AAClB,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GAAGjC,IAAIkC,SAAS;AAEzD,IAAI,CAACF,KAAK;IACR,MAAM,IAAIG,MAAM;AAClB;AAEAC,QAAQC,QAAQ,GAAG,MAAMC,IAAAA,oBAAS,EAAC;IACjC9D;IACAqD;IACAC;IACAC;IACAC;IACAC;IACAnD;IAEAC;IACAC;IACAC;IACAC;IACAC;IAEAC;IACAC;AACF"}
|
package/build/worker.js
CHANGED
|
@@ -1,12 +1,58 @@
|
|
|
1
1
|
import { workerData } from 'node:worker_threads';
|
|
2
|
+
import { SourceTextModule, SyntheticModule, createContext } from 'node:vm';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
2
5
|
import { benchmark } from "./runner.js";
|
|
3
|
-
const { setupCode, teardownCode, preCode, runCode, postCode, data, warmupCycles, minCycles, absThreshold, relThreshold, durationsSAB, controlSAB } = workerData;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
6
|
+
const { baseUrl, setupCode, teardownCode, preCode, runCode, postCode, data, warmupCycles, minCycles, absThreshold, relThreshold, gcObserver = true, durationsSAB, controlSAB } = workerData;
|
|
7
|
+
const serialize = (code)=>code ? code : '() => {}';
|
|
8
|
+
const source = `
|
|
9
|
+
export const setup = ${serialize(setupCode)};
|
|
10
|
+
export const teardown = ${serialize(teardownCode)};
|
|
11
|
+
export const pre = ${serialize(preCode)};
|
|
12
|
+
export const run = ${serialize(runCode)};
|
|
13
|
+
export const post = ${serialize(postCode)};
|
|
14
|
+
`;
|
|
15
|
+
const context = createContext({
|
|
16
|
+
console,
|
|
17
|
+
Buffer
|
|
18
|
+
});
|
|
19
|
+
const imports = new Map();
|
|
20
|
+
const mod = new SourceTextModule(source, {
|
|
21
|
+
identifier: baseUrl,
|
|
22
|
+
context,
|
|
23
|
+
initializeImportMeta (meta) {
|
|
24
|
+
meta.url = baseUrl;
|
|
25
|
+
},
|
|
26
|
+
importModuleDynamically (specifier, referencingModule) {
|
|
27
|
+
const base = referencingModule.identifier ?? baseUrl;
|
|
28
|
+
const resolveFrom = createRequire(fileURLToPath(base));
|
|
29
|
+
return import(resolveFrom.resolve(specifier));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
await mod.link(async (specifier, referencingModule)=>{
|
|
33
|
+
const base = referencingModule.identifier ?? baseUrl;
|
|
34
|
+
const resolveFrom = createRequire(fileURLToPath(base));
|
|
35
|
+
const target = resolveFrom.resolve(specifier);
|
|
36
|
+
const cached = imports.get(target);
|
|
37
|
+
if (cached) return cached;
|
|
38
|
+
const importedModule = await import(target);
|
|
39
|
+
const exportNames = Object.keys(importedModule);
|
|
40
|
+
const imported = new SyntheticModule(exportNames, ()=>{
|
|
41
|
+
exportNames.forEach((key)=>imported.setExport(key, importedModule[key]));
|
|
42
|
+
}, {
|
|
43
|
+
identifier: target,
|
|
44
|
+
context: referencingModule.context
|
|
45
|
+
});
|
|
46
|
+
imports.set(target, imported);
|
|
47
|
+
return imported;
|
|
48
|
+
});
|
|
49
|
+
await mod.evaluate();
|
|
50
|
+
const { setup, teardown, pre, run, post } = mod.namespace;
|
|
51
|
+
if (!run) {
|
|
52
|
+
throw new Error('Benchmark run function is required');
|
|
53
|
+
}
|
|
54
|
+
process.exitCode = await benchmark({
|
|
55
|
+
baseUrl,
|
|
10
56
|
setup,
|
|
11
57
|
teardown,
|
|
12
58
|
pre,
|
|
@@ -17,9 +63,9 @@ const exitCode = await benchmark({
|
|
|
17
63
|
minCycles,
|
|
18
64
|
absThreshold,
|
|
19
65
|
relThreshold,
|
|
66
|
+
gcObserver,
|
|
20
67
|
durationsSAB,
|
|
21
68
|
controlSAB
|
|
22
69
|
});
|
|
23
|
-
process.exit(exitCode);
|
|
24
70
|
|
|
25
71
|
//# sourceMappingURL=worker.js.map
|
package/build/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport { benchmark } from './runner.js';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["import { workerData } from 'node:worker_threads';\nimport { SourceTextModule, SyntheticModule, createContext } from 'node:vm';\nimport { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport { benchmark } from './runner.js';\nimport { WorkerOptions } from './types.js';\n\nconst {\n baseUrl,\n setupCode,\n teardownCode,\n preCode,\n runCode,\n postCode,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver = true,\n\n durationsSAB,\n controlSAB,\n}: WorkerOptions = workerData;\n\nconst serialize = (code?: string) => (code ? code : '() => {}');\n\nconst source = `\nexport const setup = ${serialize(setupCode)};\nexport const teardown = ${serialize(teardownCode)};\nexport const pre = ${serialize(preCode)};\nexport const run = ${serialize(runCode)};\nexport const post = ${serialize(postCode)};\n `;\n\nconst context = createContext({ console, Buffer });\nconst imports = new Map<string, SyntheticModule>();\nconst mod = new SourceTextModule(source, {\n identifier: baseUrl,\n context,\n initializeImportMeta(meta) {\n meta.url = baseUrl;\n },\n importModuleDynamically(specifier, referencingModule) {\n const base = referencingModule.identifier ?? baseUrl;\n const resolveFrom = createRequire(fileURLToPath(base));\n return import(resolveFrom.resolve(specifier));\n },\n});\n\nawait mod.link(async (specifier, referencingModule) => {\n const base = referencingModule.identifier ?? baseUrl;\n const resolveFrom = createRequire(fileURLToPath(base));\n const target = resolveFrom.resolve(specifier);\n const cached = imports.get(target);\n if (cached) return cached;\n\n const importedModule = await import(target);\n const exportNames = Object.keys(importedModule);\n const imported = new SyntheticModule(\n exportNames,\n () => {\n exportNames.forEach((key) => imported.setExport(key, importedModule[key]));\n },\n { identifier: target, context: referencingModule.context },\n );\n imports.set(target, imported);\n return imported;\n});\n\nawait mod.evaluate();\nconst { setup, teardown, pre, run, post } = mod.namespace as any;\n\nif (!run) {\n throw new Error('Benchmark run function is required');\n}\n\nprocess.exitCode = await benchmark({\n baseUrl,\n setup,\n teardown,\n pre,\n run,\n post,\n data,\n\n warmupCycles,\n minCycles,\n absThreshold,\n relThreshold,\n gcObserver,\n\n durationsSAB,\n controlSAB,\n});\n"],"names":["workerData","SourceTextModule","SyntheticModule","createContext","createRequire","fileURLToPath","benchmark","baseUrl","setupCode","teardownCode","preCode","runCode","postCode","data","warmupCycles","minCycles","absThreshold","relThreshold","gcObserver","durationsSAB","controlSAB","serialize","code","source","context","console","Buffer","imports","Map","mod","identifier","initializeImportMeta","meta","url","importModuleDynamically","specifier","referencingModule","base","resolveFrom","resolve","link","target","cached","get","importedModule","exportNames","Object","keys","imported","forEach","key","setExport","set","evaluate","setup","teardown","pre","run","post","namespace","Error","process","exitCode"],"mappings":"AAAA,SAASA,UAAU,QAAQ,sBAAsB;AACjD,SAASC,gBAAgB,EAAEC,eAAe,EAAEC,aAAa,QAAQ,UAAU;AAC3E,SAASC,aAAa,QAAQ,cAAc;AAC5C,SAASC,aAAa,QAAQ,WAAW;AACzC,SAASC,SAAS,QAAQ,cAAc;AAGxC,MAAM,EACJC,OAAO,EACPC,SAAS,EACTC,YAAY,EACZC,OAAO,EACPC,OAAO,EACPC,QAAQ,EACRC,IAAI,EAEJC,YAAY,EACZC,SAAS,EACTC,YAAY,EACZC,YAAY,EACZC,aAAa,IAAI,EAEjBC,YAAY,EACZC,UAAU,EACX,GAAkBpB;AAEnB,MAAMqB,YAAY,CAACC,OAAmBA,OAAOA,OAAO;AAEpD,MAAMC,SAAS,CAAC;qBACK,EAAEF,UAAUb,WAAW;wBACpB,EAAEa,UAAUZ,cAAc;mBAC/B,EAAEY,UAAUX,SAAS;mBACrB,EAAEW,UAAUV,SAAS;oBACpB,EAAEU,UAAUT,UAAU;EACxC,CAAC;AAEH,MAAMY,UAAUrB,cAAc;IAAEsB;IAASC;AAAO;AAChD,MAAMC,UAAU,IAAIC;AACpB,MAAMC,MAAM,IAAI5B,iBAAiBsB,QAAQ;IACvCO,YAAYvB;IACZiB;IACAO,sBAAqBC,IAAI;QACvBA,KAAKC,GAAG,GAAG1B;IACb;IACA2B,yBAAwBC,SAAS,EAAEC,iBAAiB;QAClD,MAAMC,OAAOD,kBAAkBN,UAAU,IAAIvB;QAC7C,MAAM+B,cAAclC,cAAcC,cAAcgC;QAChD,OAAO,MAAM,CAACC,YAAYC,OAAO,CAACJ;IACpC;AACF;AAEA,MAAMN,IAAIW,IAAI,CAAC,OAAOL,WAAWC;IAC/B,MAAMC,OAAOD,kBAAkBN,UAAU,IAAIvB;IAC7C,MAAM+B,cAAclC,cAAcC,cAAcgC;IAChD,MAAMI,SAASH,YAAYC,OAAO,CAACJ;IACnC,MAAMO,SAASf,QAAQgB,GAAG,CAACF;IAC3B,IAAIC,QAAQ,OAAOA;IAEnB,MAAME,iBAAiB,MAAM,MAAM,CAACH;IACpC,MAAMI,cAAcC,OAAOC,IAAI,CAACH;IAChC,MAAMI,WAAW,IAAI9C,gBACnB2C,aACA;QACEA,YAAYI,OAAO,CAAC,CAACC,MAAQF,SAASG,SAAS,CAACD,KAAKN,cAAc,CAACM,IAAI;IAC1E,GACA;QAAEpB,YAAYW;QAAQjB,SAASY,kBAAkBZ,OAAO;IAAC;IAE3DG,QAAQyB,GAAG,CAACX,QAAQO;IACpB,OAAOA;AACT;AAEA,MAAMnB,IAAIwB,QAAQ;AAClB,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GAAG7B,IAAI8B,SAAS;AAEzD,IAAI,CAACF,KAAK;IACR,MAAM,IAAIG,MAAM;AAClB;AAEAC,QAAQC,QAAQ,GAAG,MAAMxD,UAAU;IACjCC;IACA+C;IACAC;IACAC;IACAC;IACAC;IACA7C;IAEAC;IACAC;IACAC;IACAC;IACAC;IAEAC;IACAC;AACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import 'overtake';
|
|
2
|
+
|
|
3
|
+
const baseline = benchmark('accuracy tuning feed', () => {
|
|
4
|
+
const bytes = 131_072;
|
|
5
|
+
const uints = new Uint32Array(bytes / 4);
|
|
6
|
+
for (let i = 0; i < uints.length; i++) {
|
|
7
|
+
uints[i] = (i * 31) ^ 0x9e3779b1;
|
|
8
|
+
}
|
|
9
|
+
const src = Buffer.alloc(bytes, 7);
|
|
10
|
+
const dst = Buffer.allocUnsafe(bytes);
|
|
11
|
+
|
|
12
|
+
return { uints, src, dst };
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
baseline
|
|
16
|
+
.target('deterministic math', () => {
|
|
17
|
+
return { scratch: 0 };
|
|
18
|
+
})
|
|
19
|
+
.measure('sum uint32 array', (ctx, { uints }) => {
|
|
20
|
+
let acc = ctx.scratch;
|
|
21
|
+
for (let round = 0; round < 8; round++) {
|
|
22
|
+
for (let i = 0; i < uints.length; i++) {
|
|
23
|
+
acc += uints[i];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
ctx.scratch = acc;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
baseline.target('buffer reuse copy').measure('copy preallocated buffer', (_, { src, dst }) => {
|
|
30
|
+
for (let round = 0; round < 8; round++) {
|
|
31
|
+
dst.set(src);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
baseline
|
|
36
|
+
.target('buffer reuse xor')
|
|
37
|
+
.measure('xor in place', (_, { src, dst }) => {
|
|
38
|
+
for (let round = 0; round < 4; round++) {
|
|
39
|
+
for (let i = 0; i < src.length; i++) {
|
|
40
|
+
dst[i] ^= src[i];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
.pre((_, { dst }) => {
|
|
45
|
+
dst.fill(0);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
baseline.target('steady loop baseline').measure('counter increment', () => {
|
|
49
|
+
let x = 0;
|
|
50
|
+
for (let i = 0; i < 200_000; i++) {
|
|
51
|
+
x += (i & 1023) >>> 0;
|
|
52
|
+
}
|
|
53
|
+
return x;
|
|
54
|
+
});
|
package/examples/complete.ts
CHANGED
|
@@ -29,7 +29,7 @@ v8Target
|
|
|
29
29
|
// executed before measurement
|
|
30
30
|
})
|
|
31
31
|
.post(async (_ctx, _input) => {
|
|
32
|
-
// executed
|
|
32
|
+
// executed after measurement
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
v8Target
|
|
@@ -64,11 +64,11 @@ jsonTarget
|
|
|
64
64
|
// executed before measurement
|
|
65
65
|
})
|
|
66
66
|
.post(async (_ctx, _input) => {
|
|
67
|
-
// executed
|
|
67
|
+
// executed after measurement
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
jsonTarget
|
|
71
|
-
.measure('
|
|
71
|
+
.measure('parse', ({ parse, serialized }) => {
|
|
72
72
|
parse(serialized);
|
|
73
73
|
})
|
|
74
74
|
.pre(async (ctx, input) => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Demonstrates custom report types and statistics
|
|
2
|
+
// CLI mode: npx overtake examples/custom-reports.ts -f table -r ops mean median p95 p99
|
|
3
|
+
// Programmatic mode: node examples/custom-reports.js
|
|
4
|
+
import { Benchmark, printTableReports } from '../build/index.js';
|
|
5
|
+
|
|
6
|
+
const performanceSuite = new Benchmark('10K numbers', () => Array.from({ length: 10_000 }, () => Math.random() * 1000));
|
|
7
|
+
|
|
8
|
+
// Compare different rounding methods
|
|
9
|
+
performanceSuite.target('rounding methods').measure('Math.floor', (_, numbers) => {
|
|
10
|
+
for (const n of numbers) Math.floor(n);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Execute with custom statistics
|
|
14
|
+
const reports = await performanceSuite.execute({
|
|
15
|
+
workers: 4,
|
|
16
|
+
minCycles: 100,
|
|
17
|
+
maxCycles: 500,
|
|
18
|
+
reportTypes: ['ops', 'mean', 'median', 'p50', 'p95', 'p99', 'min', 'max'] as const,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
printTableReports(reports);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Demonstrates correct import patterns for worker context
|
|
2
|
+
// Run: npx overtake examples/imports.ts
|
|
3
|
+
import 'overtake';
|
|
4
|
+
|
|
5
|
+
const importExamples = benchmark('test data', () => Buffer.from('hello world'));
|
|
6
|
+
|
|
7
|
+
// Node built-in modules work normally
|
|
8
|
+
importExamples
|
|
9
|
+
.target('node built-ins', async () => {
|
|
10
|
+
const { createHash } = await import('node:crypto');
|
|
11
|
+
return { createHash };
|
|
12
|
+
})
|
|
13
|
+
.measure('sha256 hash', ({ createHash }, buffer) => {
|
|
14
|
+
createHash('sha256').update(buffer).digest('hex');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Relative imports resolve relative to benchmark file
|
|
18
|
+
const localFilesTarget = importExamples.target('local files', async () => {
|
|
19
|
+
const { DEFAULT_CYCLES, Control } = await import('../build/types.js');
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
DEFAULT_CYCLES,
|
|
23
|
+
Control,
|
|
24
|
+
// You can also define functions here
|
|
25
|
+
processData: (data: Buffer) => data.length,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
localFilesTarget.measure('use imported constant', ({ DEFAULT_CYCLES }) => {
|
|
30
|
+
DEFAULT_CYCLES > 100;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
localFilesTarget.measure('use local function', ({ processData }, buffer) => {
|
|
34
|
+
processData(buffer);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Memory management pattern - prevent GC during measurements
|
|
38
|
+
importExamples
|
|
39
|
+
.target('memory management', () => {
|
|
40
|
+
const gcBlock = new Set();
|
|
41
|
+
return { gcBlock };
|
|
42
|
+
})
|
|
43
|
+
.measure('without GC', ({ gcBlock }, buffer) => {
|
|
44
|
+
const result = Buffer.concat([buffer, buffer]);
|
|
45
|
+
gcBlock.add(result); // Keep reference alive
|
|
46
|
+
result.length;
|
|
47
|
+
});
|