ostia 0.1.5 → 0.1.6
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 +50 -0
- package/chunk-nfgy545q.js +4 -0
- package/chunk-tw064qem.js +21 -0
- package/cli.js +30 -13
- package/index.d.ts +14 -0
- package/index.js +1 -1
- package/package.json +1 -1
- package/runner.ts +4 -4
- package/chunk-gsjgejr1.js +0 -21
- package/chunk-y1gkhb0y.js +0 -4
package/README.md
CHANGED
|
@@ -176,6 +176,32 @@ rest sharing a process). `--jobs` then pools across those per-task processes the
|
|
|
176
176
|
it pools across per-file ones, so pair a higher `--jobs` with `--isolate` deliberately -
|
|
177
177
|
overhead now scales with task count, not file count.
|
|
178
178
|
|
|
179
|
+
`--gc` calls `Bun.gc(true)` between trials (default: off, which hides allocation cost as
|
|
180
|
+
Bun/V8 batch calls together and amortize it away). `task(name, fn, { gc })` /
|
|
181
|
+
`group(name, fn, { gc })` override the suite-wide default per task or group, the same
|
|
182
|
+
override pattern as `isolate` - useful when a few allocation-heavy tasks need GC settled
|
|
183
|
+
between trials but the rest of the suite doesn't.
|
|
184
|
+
|
|
185
|
+
`--preload PATH` (repeatable) imports a script before each suite file loads, in the same
|
|
186
|
+
subprocess - the same shape as Bun's own `--preload` / `bunfig.toml`'s `preload` array. Use
|
|
187
|
+
it to install globals a suite needs at import time (jsdom's `document`/`window`) or register
|
|
188
|
+
a `Bun.plugin()` file-loader (e.g. compiling `.svelte`/`.vue` SFCs) before the suite's own
|
|
189
|
+
top-level code runs. Multiple `--preload` scripts run in the order given, so state one
|
|
190
|
+
installs (a plugin registration, a global) is visible to the next and to the suite itself.
|
|
191
|
+
ostia ships none of this itself - just the hook point:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// bench/jsdom-setup.ts
|
|
195
|
+
import { JSDOM } from "jsdom"
|
|
196
|
+
const dom = new JSDOM("<!doctype html>")
|
|
197
|
+
Object.assign(globalThis, { document: dom.window.document, window: dom.window })
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
ostia bench --preload ./bench/jsdom-setup.ts bench/*.dom.bench.ts
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
|
|
179
205
|
```
|
|
180
206
|
Command Mean [ms] Min…Max [ms] Relative
|
|
181
207
|
--------------------------------------------------------------------------------------
|
|
@@ -370,6 +396,7 @@ import {
|
|
|
370
396
|
bench,
|
|
371
397
|
group,
|
|
372
398
|
task,
|
|
399
|
+
range,
|
|
373
400
|
compareDocuments,
|
|
374
401
|
renderers,
|
|
375
402
|
saveDocument,
|
|
@@ -463,6 +490,29 @@ group("parse", () => {
|
|
|
463
490
|
})
|
|
464
491
|
```
|
|
465
492
|
|
|
493
|
+
### `range(start, end, multiplier?)` → `number[]`
|
|
494
|
+
|
|
495
|
+
Geometric sweep points for parameterizing `task()` over a size dimension - mitata's
|
|
496
|
+
`.range(name, start, end, multiplier)` point generation (default multiplier `8`, always
|
|
497
|
+
ending on `end` even if the last step overshot it), without the name templating: build
|
|
498
|
+
the task name yourself in the loop.
|
|
499
|
+
|
|
500
|
+
```ts
|
|
501
|
+
import { group, task, range } from "ostia"
|
|
502
|
+
|
|
503
|
+
group("parse", () => {
|
|
504
|
+
for (const size of range(100, 10_000)) {
|
|
505
|
+
const input = buildInput(size) // setup, runs once per point, unmeasured
|
|
506
|
+
task(`${size} items`, () => parse(input))
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
range(100, 10_000) // -> [100, 800, 6400, 10000]
|
|
513
|
+
range(100, 100_000) // -> [100, 800, 6400, 51200, 100000]
|
|
514
|
+
```
|
|
515
|
+
|
|
466
516
|
```ts
|
|
467
517
|
// demo.ts
|
|
468
518
|
import { bench } from "ostia"
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
function h(n){return JSON.stringify(F(n))}function F(n){if(Array.isArray(n))return n.map(F);if(n!==null&&typeof n==="object"){let a={};for(let d of Object.keys(n).sort())a[d]=F(n[d]);return a}return n}function e(n,...a){let d=Bun.CryptoHasher.hash("sha256",h(a),"hex");return`${n}_${d.slice(0,16)}`}var c="0.1.0";function r(n,a){return{schemaVersion:1,toolVersion:c,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:n,runs:a}}function u(n,a){return{id:e("wl","subprocess",n,process.cwd()),kind:"subprocess",command:n,label:a}}function R(n,a){return{id:e("wl","inprocess",n.name,n.toString()),kind:"inprocess",label:a}}function P(n,a,d={}){return{id:e("wl","inprocess-entry",n,a),kind:"inprocess",entry:{file:n,task:a,...d.group!==void 0&&{group:d.group}},...d.label!==void 0&&{label:d.label},...d.baseline!==void 0&&{baseline:d.baseline},...d.description!==void 0&&{description:d.description},...d.groupDescription!==void 0&&{groupDescription:d.groupDescription},...d.isolated!==void 0&&{isolated:d.isolated}}}function i(n){return{id:e("run",n.workload.id,"timing",n.configFingerprint,Bun.version,c),workloadId:n.workload.id,phase:"timing",instrumented:!1,configFingerprint:n.configFingerprint,trials:n.trials,timing:n.timing,warnings:n.warnings,artifacts:[],memory:Q(n.trials)}}function Q(n){let a=n.map((d)=>d.maxRssBytes).filter((d)=>d!==void 0);if(a.length===0)return;return{origin:"resourceUsage",perTrial:n.map((d)=>({rssBytes:d.maxRssBytes})),maxRssBytes:Math.max(...a)}}function b(n){return{id:e("run",n.workload.id,n.phase,n.configFingerprint,Bun.version,c),workloadId:n.workload.id,phase:n.phase,instrumented:!0,configFingerprint:n.configFingerprint,trials:[{i:0,wallNs:n.diagnosticWallNs,exitCode:n.exitCode}],diagnosticWallNs:n.diagnosticWallNs,cpu:n.cpu,heap:n.heap,jit:n.jit,warnings:n.warnings,artifacts:n.artifacts}}async function T(n,a,d){let f=await Bun.file(d).arrayBuffer(),w=new Bun.CryptoHasher("sha256");return w.update(f),{id:e("art",n,a,d),kind:a,path:d,sha256:w.digest("hex"),bytes:f.byteLength}}function s(n){return e("cfg",n)}function k(n){return`${JSON.stringify(F(n),null,2)}
|
|
3
|
+
`}async function o(n,a){await Bun.write(a,k(n))}async function t(n){let a=await Bun.file(n).text();return JSON.parse(a)}var G=[],W;function U(n,a,d){let g=W;W={name:n,description:d?.description,isolate:d?.isolate,gc:d?.gc};try{a()}finally{W=g}}function M(n,a,d){G.push({groupName:W?.name,groupDescription:W?.description,groupIsolate:W?.isolate,groupGc:W?.gc,name:n,fn:a,baseline:d?.baseline,opts:d})}function I(){return G}function C(){G.length=0,W=void 0}function m(n){return n.groupName?`${n.groupName}/${n.name}`:n.name}function N(n,a){return n.opts?.isolate??n.groupIsolate??a}function D(n,a){return n.opts?.gc??n.groupGc??a}function v(n,a){if(!a)return[...n];let d=new RegExp(a);return n.filter((g)=>d.test(m(g)))}function l(n){if(n.length===0)throw Error("computeTimingStats: samples must be non-empty");let a=n.length,d=L(n),g=0;for(let y=0;y<a;y++)g+=n[y];let f=g/a,w=O(d,0.5),x=0;for(let y=0;y<a;y++){let S=n[y]-f;x+=S*S}let A=Math.sqrt(x/a),H=d[0],B=d[a-1],q=O(d,0.25),_=O(d,0.75),E=_-q,z=q-1.5*E,V=_+1.5*E,K=q-3*E,Z=_+3*E,J=0,j=0;for(let y=0;y<a;y++){let S=n[y];if(S<K||S>Z)j++;else if(S<z||S>V)J++}return{unit:"ns",samples:n,mean:f,median:w,stddev:A,min:H,max:B,outliers:{mild:J,severe:j}}}function L(n){let a=new Float64Array(n.length);return a.set(n),a.sort(),a}function O(n,a){let d=n.length;if(d===1)return n[0];let g=a*(d-1),f=Math.floor(g),w=Math.ceil(g);if(f===w)return n[f];let x=g-f;return n[f]*(1-x)+n[w]*x}var X=5000000,Y=200;function p(n,a,d="subprocess"){let g=[],f=n.samples[0];if(f!==void 0){let x=L(n.samples),A=O(x,0.25),B=O(x,0.75)-A;if(f>n.median+3*B&&B>0)g.push({code:"slow-first-run",message:`First run took ${(f/1e6).toFixed(2)}ms, much slower than the median ${(n.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:f,medianNs:n.median}})}if(n.outliers.mild+n.outliers.severe>0)g.push({code:"outliers-detected",message:`${n.outliers.mild+n.outliers.severe} outlier(s) detected (${n.outliers.severe} severe, ${n.outliers.mild} mild).`,data:n.outliers});if(d==="subprocess"&&n.median<X)g.push({code:"fast-command",message:`Median run time (${(n.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:n.median}});if(d==="inprocess"&&n.median<Y)g.push({code:"below-timer-resolution",message:`Median run time (${n.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:n.median}});let w=a.filter((x)=>x!==void 0&&x!==0);if(w.length>0)g.push({code:"nonzero-exit",message:`${w.length} of ${a.length} trial(s) exited non-zero.`,data:{exitCodes:w}});return g}
|
|
4
|
+
export{h,e,c,r,u,R,P,i,b,T,s,k,o,t,l,p,U,M,I,C,m,N,D,v};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{h,e,r,u,R,i,b,T,s,k,t,l,p}from"./chunk-nfgy545q.js";function _e(o){return o.startsWith("file://")?o.slice(7):o}function ie(o,N,c){let I=o.nodes,m=I.length,v=new Map,C=[],P=new Map,U=new Int32Array(m);for(let W=0;W<m;W++){let E=I[W],B=E.callFrame,H=_e(B.url),G=v.get(B.functionName);if(G===void 0)G=new Map,v.set(B.functionName,G);let Y=G.get(H);if(Y===void 0)Y=C.length,G.set(H,Y),C.push({key:e("fr",B.functionName,H),name:B.functionName,url:H||void 0,line:B.lineNumber>=0?B.lineNumber:void 0,col:B.columnNumber>=0?B.columnNumber:void 0});U[W]=Y,P.set(E.id,W)}let D=Array(m);for(let W=0;W<m;W++){let E=I[W];D[W]={id:E.id,frameIx:U[P.get(E.id)],children:E.children??[]}}let M=new Float64Array(m),O=new Float64Array(m),{samples:A,timeDeltas:z}=o;for(let W=0;W<A.length;W++){let E=P.get(A[W]);if(E===void 0)continue;M[E]+=z[W]??0,O[E]+=1}let K=new Int32Array(m).fill(-1);for(let W=0;W<m;W++){let E=I[W].children;if(!E)continue;for(let B of E){let H=P.get(B);if(H!==void 0)K[H]=W}}let _=[],J=[];for(let W=m-1;W>=0;W--)if(K[W]===-1)J.push(W);while(J.length>0){let W=J.pop();_.push(W);let E=I[W].children;if(!E)continue;for(let B of E){let H=P.get(B);if(H!==void 0&&K[H]===W)J.push(H)}}let V=new Float64Array(m);for(let W=_.length-1;W>=0;W--){let E=_[W];V[E]+=M[E];let B=K[E];if(B>=0)V[B]+=V[E]}let L=Array(C.length),j=[];for(let W=0;W<m;W++){let E=D[W].frameIx,B=L[E];if(B)B.selfUs+=M[W],B.totalUs+=V[W],B.samples+=O[W];else{let H={frameIx:E,selfUs:M[W],totalUs:V[W],samples:O[W]};L[E]=H,j.push(H)}}return{origin:N,samplingIntervalUs:c,frames:C,nodes:D,totals:j.sort((W,E)=>E.selfUs-W.selfUs),samples:{nodeIds:o.samples,timeDeltasUs:o.timeDeltas}}}function Le(o,N,c,I){let m=["--cpu-prof","--cpu-prof-dir",N,"--cpu-prof-name",c,"--cpu-prof-interval",String(I)],v=o[0];if(v==="bun"||v?.endsWith("/bun"))return[v,...m,...o.slice(1)];return o}async function fe(o){let N=`${o.artifactDir}/${o.fileName}`,c=o.argv[0],I=c==="bun"||c?.endsWith("/bun"),m=Le(o.argv,o.artifactDir,o.fileName,o.intervalUs),v=I?o.env:{...process.env,...o.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${o.artifactDir} --cpu-prof-name ${o.fileName} --cpu-prof-interval ${o.intervalUs}`},C=Bun.nanoseconds(),U=await Bun.spawn(m,{cwd:o.cwd,env:v,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,D=Bun.nanoseconds()-C,M=Bun.file(N);if(!await M.exists())return{diagnosticWallNs:D,exitCode:U,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${N} after exit ${U}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:N,argv:o.argv}}]};let O=await M.json(),A=ie(O,"cpu-prof",o.intervalUs),z=O.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:D,exitCode:U,artifactPath:N,cpu:A,warnings:z}}function ge(o,N="heap-prof"){let{node_fields:c,node_types:I}=o.snapshot.meta,m=c.indexOf("type"),v=c.indexOf("self_size"),C=c.length,P=I[0];if(m===-1||v===-1||!Array.isArray(P))return{origin:N,typeCounts:[],objectCount:o.snapshot.node_count};let U=P.length,D=Array(U),M=new Map,O=[],A=0,z=o.nodes,K=z.length;for(let j=0;j<K;j+=C){let W=z[j+m],E=z[j+v]??0;A+=E;let B;if(W>=0&&W<U){if(B=D[W],B===void 0)B={type:P[W],count:0,bytes:0},D[W]=B,O.push(B)}else{let H=`unknown(${W})`;if(B=M.get(H),B===void 0)B={type:H,count:0,bytes:0},M.set(H,B),O.push(B)}B.count++,B.bytes+=E}let _=O.sort((j,W)=>W.count-j.count),J=_.slice(0,20),V=_.slice(20),L=J.map(({type:j,count:W,bytes:E})=>({type:j,count:W,retainedBytes:E}));if(V.length>0){let j=0,W=0;for(let E of V)j+=E.count,W+=E.bytes;L.push({type:"other",count:j,retainedBytes:W})}return{origin:N,heapSizeBytes:A,objectCount:o.snapshot.node_count,typeCounts:L}}function He(o,N,c){let I=["--heap-prof","--heap-prof-dir",N,"--heap-prof-name",c],m=o[0];if(m==="bun"||m?.endsWith("/bun"))return[m,...I,...o.slice(1)];return o}async function he(o){let N=`${o.artifactDir}/${o.fileName}`,c=o.argv[0],I=c==="bun"||c?.endsWith("/bun"),m=He(o.argv,o.artifactDir,o.fileName),v=I?o.env:{...process.env,...o.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${o.artifactDir} --heap-prof-name ${o.fileName}`},C=Bun.nanoseconds(),U=await Bun.spawn(m,{cwd:o.cwd,env:v,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,D=Bun.nanoseconds()-C,M=Bun.file(N);if(!await M.exists())return{diagnosticWallNs:D,exitCode:U,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${N} after exit ${U}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:N,argv:o.argv}}]};let O=await M.json(),A=ge(O,"heap-prof");return{diagnosticWallNs:D,exitCode:U,artifactPath:N,heap:A,warnings:[]}}import{Session as Je}from"inspector/promises";var ze=1000;async function be(o,N={}){let c=N.intervalUs??ze,I=new Je;I.connect();let m=Bun.nanoseconds();try{await I.post("Profiler.enable"),await I.post("Profiler.setSamplingInterval",{interval:c}),await I.post("Profiler.start");let v=await o(),{profile:C}=await I.post("Profiler.stop"),P=Bun.nanoseconds()-m,U=ie(C,"inspector",c);return{result:v,cpu:U,diagnosticWallNs:P}}finally{I.disconnect()}}import{profile as Ke}from"bun:jsc";var Ve=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),ye=4294967295;function we(o,N){let c=N??o.interval*1e6,I=new Map,m=[];function v(B,H,G,Y){let Q=I.get(B);if(Q===void 0)Q=new Map,I.set(B,Q);let q=H??"",Z=Q.get(q);if(Z===void 0)Z=m.length,Q.set(q,Z),m.push({key:e("fr",B,q),name:B,url:H,line:G,col:Y});return Z}function C(B){let H=B.line===ye,G=H?void 0:B.line-1,Y=H||B.column===ye?void 0:B.column-1;return v(B.name,B.sourceURL,G,Y)}let P=v("(root)",void 0,void 0,void 0),U=1,D={id:0,frameIx:P,children:new Map,selfUs:0,samples:0,totalUs:0},M=new Map([[0,D]]),O={llint:0,baseline:0,dfg:0,ftl:0},A=new Map,z=[],K=[];for(let B of o.traces){let H=B.frames,G=D;for(let q=H.length-1;q>=0;q--){let Z=C(H[q]),te=G.children.get(Z);if(!te)te={id:U++,frameIx:Z,children:new Map,selfUs:0,samples:0,totalUs:0},G.children.set(Z,te),M.set(te.id,te);G=te}G.selfUs+=c,G.samples+=1,z.push(G.id),K.push(c);let Y=H[0],Q=Y&&Ve.get(Y.category);if(Q){O[Q]++;let q=A.get(Q)??new Map;q.set(G.frameIx,(q.get(G.frameIx)??0)+1),A.set(Q,q)}}function _(B){let H=B.selfUs;for(let G of B.children.values())H+=_(G);return B.totalUs=H,H}_(D);let J=new Map;function V(B){let H=J.get(B.frameIx);if(H)H.selfUs+=B.selfUs,H.totalUs+=B.totalUs,H.samples+=B.samples;else J.set(B.frameIx,{frameIx:B.frameIx,selfUs:B.selfUs,totalUs:B.totalUs,samples:B.samples});for(let G of B.children.values())V(G)}V(D);let L=[...M.values()].map((B)=>({id:B.id,frameIx:B.frameIx,children:[...B.children.values()].map((H)=>H.id)})),j={origin:"jsc-profile",samplingIntervalUs:c,frames:m,nodes:L,totals:[...J.values()].sort((B,H)=>H.selfUs-B.selfUs),samples:{nodeIds:z,timeDeltasUs:K}},W=[...A.entries()].flatMap(([B,H])=>[...H.entries()].sort((G,Y)=>Y[1]-G[1]).slice(0,3).map(([G,Y])=>({tier:B,frameKey:m[G].key,samples:Y})));return{cpu:j,jit:{origin:"jsc-profile",tiers:O,topFramesByTier:W}}}var Ge=1000;async function xe(o,N={}){let c=N.intervalUs??Ge,I,m=Bun.nanoseconds(),v=await Ke(async()=>(I=await o(),I),c),C=Bun.nanoseconds()-m,{cpu:P,jit:U}=we(v.stackTraces,c);return{result:I,cpu:P,jit:U,diagnosticWallNs:C}}async function le(o){let N=Bun.nanoseconds(),c=Bun.spawn(o.argv,{cwd:o.cwd,env:o.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),I=await c.exited,m=Bun.nanoseconds(),v=c.resourceUsage?.();return{wallNs:m-N,exitCode:I,userNs:v?Number(v.cpuTime.user)*1000:void 0,systemNs:v?Number(v.cpuTime.system)*1000:void 0,maxRssBytes:v?.maxRSS}}function Re(o){return o.trim().split(/\s+/).filter(Boolean)}var Ye=10,qe=3000000000,Qe=3;async function g(o){let N=o.warmup??Qe;for(let M=0;M<N;M++)await le(o);let c=[],I=o.runs??o.minRuns??Ye,m=o.runs!==void 0?0:o.minTotalNs??qe,v=0,C=0;while(C<I||v<m){let M=await le(o);if(c.push({i:C,wallNs:M.wallNs,exitCode:M.exitCode,userNs:M.userNs,systemNs:M.systemNs,maxRssBytes:M.maxRssBytes}),v+=M.wallNs,C++,o.runs!==void 0&&C>=o.runs)break}let P=c.map((M)=>M.wallNs),U=l(P),D=p(U,c.map((M)=>M.exitCode));return{trials:c,timing:U,warnings:D}}var Pe=new URL("./runner.ts",import.meta.url).pathname,Xe="node_modules/.cache/ostia";function x(){return Math.max(1,navigator.hardwareConcurrency||1)}async function d(o){let c=`${o.outDir??Xe}/bench-tmp`,I=o.cwd??process.cwd(),m=Math.max(1,Math.floor(o.jobs??1)),v={timeBudgetMs:o.timeBudgetMs,minSamples:o.minSamples,gc:o.gc},C=o.suites.map((D)=>D.startsWith("/")?D:`${I}/${D}`),P=(o.preload??[]).map((D)=>D.startsWith("/")?D:`${I}/${D}`),U=async(D,M)=>{let O=new Set,A=0,z,K=async()=>{while(z===void 0&&A<D.length){let _=A++;try{let J=Bun.spawn(D[_],{cwd:I,stdout:"inherit",stderr:"inherit",stdin:"ignore"});O.add(J);let V=await J.exited;if(O.delete(J),V!==0)throw Error(`Bench suite failed: ${M(_)} (runner exited ${V})`)}catch(J){z??=J instanceof Error?J:Error(String(J));for(let V of O)V.kill()}}};if(await Promise.all(Array.from({length:Math.min(m,D.length)},K)),z)throw z};try{let D=C.map((L)=>`${c}/${e("bench-plan",L)}.json`),M=C.map((L,j)=>["bun",Pe,L,D[j],JSON.stringify({...v,filter:o.filter,isolate:o.isolate,preload:P,planOnly:!0})]);await U(M,(L)=>o.suites[L]);let O=await Promise.all(D.map(async(L)=>{let{tasks:j}=await Bun.file(L).json();return j})),A=[];for(let L=0;L<O.length;L++){let j=O[L].filter((W)=>!W.isolate).map((W)=>W.id);if(j.length>0)A.push({suiteIndex:L,taskIds:j,markIsolated:!1});for(let W of O[L])if(W.isolate)A.push({suiteIndex:L,taskIds:[W.id],markIsolated:!0})}let z=A.map((L,j)=>`${c}/${e("bench-item",C[L.suiteIndex],j)}.json`),K=A.map((L,j)=>["bun",Pe,C[L.suiteIndex],z[j],JSON.stringify({...v,taskIds:L.taskIds,preload:P,...L.markIsolated&&{markIsolated:!0}})]);await U(K,(L)=>o.suites[A[L].suiteIndex]);let _=await Promise.all(z.map(t)),J=[],V=[];for(let L=0;L<O.length;L++){let j=A.findIndex((H)=>H.suiteIndex===L&&!H.markIsolated),W=j>=0?_[j]:void 0,E=0,B=new Map;A.forEach((H,G)=>{if(H.suiteIndex===L&&H.markIsolated)B.set(H.taskIds[0],_[G])});for(let H of O[L])if(H.isolate){let G=B.get(H.id);J.push(G.workloads[0]),V.push(G.runs[0])}else J.push(W.workloads[E]),V.push(W.runs[E]),E++}return r(J,V)}finally{await Bun.spawn(["rm","-rf",c]).exited}}function F(o,N,c=8){if(c<=1)throw RangeError(`range: multiplier must be > 1, got ${c}`);if(o<=0)throw RangeError(`range: start must be > 0, got ${o}`);let I=[];for(let m=o;m<=N;m*=c)I.push(m);if(!I.includes(N))I.push(N);return I}var a={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function ae(o,N){if(o===0)return N===0?0:1/0;return(N-o)/o*100}function re(o,N,c){return o.runs.find((I)=>I.workloadId===N&&I.phase===c)}function f(o,N,c=a){let I=new Set(N.workloads.map((v)=>v.id)),m=[];for(let v of o.workloads){if(!I.has(v.id))continue;let C=w(o,N,v.id,c);if(C)m.push(C)}return m}function w(o,N,c,I=a){let m=re(o,c,"timing"),v=re(N,c,"timing"),C=re(o,c,"cpu"),P=re(N,c,"cpu"),U=re(o,c,"heap"),D=re(N,c,"heap"),M=m?.id??C?.id??U?.id,O=v?.id??P?.id??D?.id;if(!M||!O)return;let A=!1,z;if(m?.timing&&v?.timing){let J=ae(m.timing.median,v.timing.median),V=ae(m.timing.mean,v.timing.mean),L=J>I.timingPct?"regressed":J<-I.timingPct?"improved":"unchanged";if(L==="regressed")A=!0;z={medianDeltaPct:J,meanDeltaPct:V,verdict:L}}let K;if(C?.cpu&&P?.cpu){let J=new Map(C.cpu.totals.map((E)=>[C.cpu.frames[E.frameIx].key,E])),V=new Map(P.cpu.totals.map((E)=>[P.cpu.frames[E.frameIx].key,E])),L=new Map(C.cpu.frames.map((E)=>[E.key,E.name])),j=new Map(P.cpu.frames.map((E)=>[E.key,E.name]));K=[...new Set([...J.keys(),...V.keys()])].map((E)=>{let B=J.get(E)?.selfUs??0,H=V.get(E)?.selfUs??0;return{frameKey:E,name:j.get(E)??L.get(E)??E,baseSelfUs:B,candSelfUs:H,deltaPct:ae(B,H)}}).sort((E,B)=>Math.abs(B.deltaPct)-Math.abs(E.deltaPct));for(let E of K)if((E.baseSelfUs>=I.minFrameSelfUs||E.candSelfUs>=I.minFrameSelfUs)&&E.deltaPct>I.frameSelfPct)A=!0}let _;if(U?.heap&&D?.heap){let J=new Map(U.heap.typeCounts.map((j)=>[j.type,j])),V=new Map(D.heap.typeCounts.map((j)=>[j.type,j]));_=[...new Set([...J.keys(),...V.keys()])].map((j)=>{let W=J.get(j),E=V.get(j);return{type:j,baseCount:W?.count??0,candCount:E?.count??0,baseBytes:W?.retainedBytes,candBytes:E?.retainedBytes,deltaPct:ae(W?.count??0,E?.count??0)}}).sort((j,W)=>Math.abs(W.deltaPct)-Math.abs(j.deltaPct));for(let j of _)if(j.deltaPct>I.heapTypePct)A=!0}return{id:e("cmp",M,O),baselineRunId:M,candidateRunId:O,timing:z,frames:K,heapTypes:_,thresholds:I,verdict:A?"fail":"pass"}}function ee(o,N){if(N){let c=o.runs.find((I)=>I.id===N);return c?.cpu?[c]:[]}return o.runs.filter((c)=>c.phase==="cpu"&&c.cpu)}function se(o){let N=o.nodes,c=N.length,I=Ze(o),m=new Int32Array(c).fill(-1);for(let U=0;U<c;U++)for(let D of N[U].children){let M=I(D);if(M!==-1)m[M]=U}let v=[];for(let U=0;U<c;U++)if(m[U]===-1)v.push(U);let C=[],P=[];for(let U=v.length-1;U>=0;U--)P.push(v[U]);while(P.length>0){let U=P.pop();C.push(U);for(let D of N[U].children){let M=I(D);if(M!==-1&&m[M]===U)P.push(M)}}return{count:c,indexOf:I,parentIx:m,roots:v,order:C}}function Ze(o){let N=o.nodes,c=N.length,I=1/0,m=-1/0,v=!0;for(let P=0;P<c;P++){let U=N[P].id;if(!Number.isInteger(U)){v=!1;break}if(U<I)I=U;if(U>m)m=U}if(v&&c>0&&m-I<c*4+64){let P=m-I+1,U=new Int32Array(P).fill(-1);for(let D=0;D<c;D++)U[N[D].id-I]=D;return(D)=>{let M=D-I;return M>=0&&M<P?U[M]:-1}}let C=new Map;for(let P=0;P<c;P++)C.set(N[P].id,P);return(P)=>C.get(P)??-1}function ke(o,N){let{count:c,indexOf:I,parentIx:m,order:v}=N,C=new Float64Array(c),P=new Float64Array(c),U=o.samples?.nodeIds??[],D=o.samples?.timeDeltasUs??[];for(let O=0;O<U.length;O++){let A=I(U[O]);if(A===-1)continue;C[A]+=D[O]??0,P[A]+=1}let M=new Float64Array(c);for(let O=v.length-1;O>=0;O--){let A=v[O];M[A]+=C[A];let z=m[A];if(z>=0)M[z]+=M[A]}return{selfUs:C,totalUs:M,samples:P}}var Te={name:"collapsed",async render(o,N={}){return{files:ee(o,N.runId).map((m)=>{let v=m.cpu,{nodes:C,frames:P}=v,U=se(v),D=Array(U.count);for(let K of U.order){let _=P[C[K].frameIx].name||"(anonymous)",J=U.parentIx[K];D[K]=J===-1?_:`${D[J]};${_}`}let M=new Float64Array(U.count),O=[],A=v.samples?.nodeIds??[];for(let K=0;K<A.length;K++){let _=U.indexOf(A[K]);if(_===-1)continue;if(M[_]++===0)O.push(_)}let z=Array(O.length);for(let K=0;K<O.length;K++){let _=O[K];z[K]=`${D[_]} ${M[_]}`}return{path:`${m.id}.collapsed.txt`,content:z.join(`
|
|
3
|
+
`)+(z.length>0?`
|
|
4
|
+
`:"")}})}}};var Ie={name:"cpuprofile",async render(o,N={}){let c=ee(o,N.runId),I=[],m=[];for(let v of c){if(v.cpu?.origin!=="cpu-prof"&&v.cpu?.origin!=="inspector"){m.push(`${v.id} (origin ${v.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let C=v.artifacts.find((U)=>U.kind==="cpuprofile");if(!C){m.push(`${v.id} (no cpuprofile artifact recorded on this run)`);continue}let P=Bun.file(C.path);if(!await P.exists()){m.push(`${v.id} (artifact missing on disk: ${C.path})`);continue}I.push({path:`${v.id}.cpuprofile`,content:await P.text()})}if(I.length===0&&m.length>0)return{text:`No .cpuprofile artifacts available:
|
|
5
|
+
${m.map((v)=>` - ${v}`).join(`
|
|
6
|
+
`)}
|
|
7
|
+
`};return{files:I}}};var $e={name:"json",async render(o){return{text:k(o)}}};var ve={name:"jsonl",async render(o){let{runs:N,...c}=o;return{text:`${[h(c),...N.map((m)=>h(m))].join(`
|
|
8
|
+
`)}
|
|
9
|
+
`}}};function ne(o){return(o/1e6).toFixed(3)}function ce(o){return o?.label??o?.command?.join(" ")??o?.entry?.task??o?.id??"unknown"}var Ce=10,Ne=10,Ue={name:"markdown",async render(o){let N=new Map(o.workloads.map((m)=>[m.id,m])),c=[];c.push("# Profile Report",""),c.push(`Bun ${o.bunVersion} \xB7 ostia ${o.toolVersion} \xB7 ${o.platform.os}/${o.platform.arch} \xB7 ${o.createdAt}`,"");let I=o.runs.filter((m)=>m.phase==="timing"&&m.timing!==void 0);if(I.length>0){c.push("## Timing",""),c.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let v of I){let C=ce(N.get(v.workloadId)),P=v.timing;c.push(`| ${C} | ${ne(P.mean)} \xB1 ${ne(P.stddev)} | ${ne(P.min)}\u2026${ne(P.max)} | ${ne(P.median)} |`)}c.push("");let m=I.filter((v)=>v.warnings.length>0);if(m.length>0){c.push("### Warnings","");for(let v of m){let C=ce(N.get(v.workloadId));for(let P of v.warnings)c.push(`- **${C}**: ${P.message} (\`${P.code}\`)`)}c.push("")}}for(let m of o.runs){if(m.phase!=="cpu"&&m.phase!=="heap")continue;let v=ce(N.get(m.workloadId));if(m.phase==="cpu"){if(c.push(`## CPU capture - ${v}`,""),c.push(`instrumented, diagnostic wall ${ne(m.diagnosticWallNs??0)}ms`,""),m.cpu){c.push(`origin: \`${m.cpu.origin}\`, interval: ${m.cpu.samplingIntervalUs}\xB5s`,""),c.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let C=m.cpu.totals.reduce((P,U)=>P+U.selfUs,0)||1;for(let P of m.cpu.totals.slice(0,Ce)){let U=m.cpu.frames[P.frameIx],D=(P.selfUs/C*100).toFixed(1);c.push(`| ${D}% | ${(P.selfUs/1000).toFixed(2)} | ${(P.totalUs/1000).toFixed(2)} | ${U?.name||"(anonymous)"} |`)}if(c.push(""),m.jit){let P=m.jit.tiers;c.push(`JIT tiers: LLInt ${P.llint} \xB7 Baseline ${P.baseline} \xB7 DFG ${P.dfg} \xB7 FTL ${P.ftl}`,"")}}}else if(c.push(`## Heap snapshot - ${v}`,""),c.push(`instrumented, diagnostic wall ${ne(m.diagnosticWallNs??0)}ms`,""),m.heap){c.push(`${m.heap.objectCount??"?"} objects, ${((m.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),c.push("| Count | Type |","|---|---|");for(let C of m.heap.typeCounts.slice(0,Ne))c.push(`| ${C.count} | ${C.type} |`);c.push("")}for(let C of m.artifacts)c.push(`- artifact: \`${C.path}\``);for(let C of m.warnings)c.push(`- ! ${C.message} (\`${C.code}\`)`);if(m.artifacts.length>0||m.warnings.length>0)c.push("")}if(o.comparisons&&o.comparisons.length>0){c.push("## Comparisons","");for(let m of o.comparisons){let v=o.runs.find((P)=>P.id===m.candidateRunId),C=ce(v?N.get(v.workloadId):void 0);if(c.push(`### ${m.verdict==="pass"?"\u2713":"\u2717"} ${C}`,""),m.timing){let P=m.timing.medianDeltaPct>0?"+":"";c.push(`- timing: ${P}${m.timing.medianDeltaPct.toFixed(1)}% median (**${m.timing.verdict}**)`)}for(let P of m.frames?.slice(0,Ce)??[]){if(Math.abs(P.deltaPct)<0.5)continue;let U=P.deltaPct>0?"+":"";c.push(`- frame \`${P.name}\`: ${U}${P.deltaPct.toFixed(1)}% self-time (${(P.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(P.candSelfUs/1000).toFixed(2)}ms)`)}for(let P of m.heapTypes?.slice(0,Ne)??[]){if(Math.abs(P.deltaPct)<0.5)continue;let U=P.deltaPct>0?"+":"";c.push(`- heap \`${P.type}\`: ${U}${P.deltaPct.toFixed(1)}% count (${P.baseCount} \u2192 ${P.candCount})`)}c.push("")}}return{text:c.join(`
|
|
10
|
+
`)}}};var en=15;function pe(o){return`n${o}`}function nn(o,N,c){return`${(o||"(anonymous)").replace(/"/g,"'")} (self ${(N/1000).toFixed(2)}ms, total ${(c/1000).toFixed(2)}ms)`}function tn(o,N,c,I){let m=[];if(I<=0)return m;for(let v=0;v<N;v++){if(v===c)continue;let C=o[v];if(m.length===I&&C<=o[m[I-1]])continue;let P=m.length;while(P>0&&o[m[P-1]]<C)P--;if(m.splice(P,0,v),m.length>I)m.pop()}return m}var De={name:"mermaid",async render(o,N={}){let c=N.topN??en;return{files:ee(o,N.runId).map((v)=>{let C=v.cpu,{nodes:P,frames:U}=C,D=se(C),{selfUs:M,totalUs:O}=ke(C,D),{parentIx:A}=D,z=D.roots[0]??-1,K=tn(M,D.count,z,c),_=new Set(z!==-1?[z]:[]),J=[];for(let L of K){J.length=0;for(let j=L;j!==-1;j=A[j])J.push(j);for(let j=J.length-1;j>=0;j--)_.add(J[j])}let V=["graph TD"];for(let L of _){let j=P[L].id;V.push(` ${pe(j)}["${nn(U[P[L].frameIx].name,M[L],O[L])}"]`)}for(let L of _){let j=A[L];if(j!==-1&&_.has(j))V.push(` ${pe(P[j].id)} --> ${pe(P[L].id)}`)}return{path:`${v.id}.mermaid.md`,content:`${V.join(`
|
|
11
|
+
`)}
|
|
12
|
+
`}})}}};function Fe(o){if(!o?.entry)return;if(o.entry.group!==void 0)return o.entry.group;let N=o.entry.task,c=N.lastIndexOf("/");return c===-1?void 0:N.slice(0,c)}function ue(o){let N=Math.min(...o.map((m)=>m.run.timing.median)),c=new Map;for(let m of o){let v=Fe(m.workload);if(v===void 0)continue;let C=c.get(v);if(C)C.push(m);else c.set(v,[m])}let I=new Map;for(let m of o){let v=Fe(m.workload);if(v===void 0){I.set(m,N);continue}let C=c.get(v)??[m],P=C.find((U)=>U.workload?.baseline);I.set(m,P?P.run.timing.median:Math.min(...C.map((U)=>U.run.timing.median)))}return I}function X(o){return Number.isFinite(o)?Number(o.toPrecision(6)):o}function rn(o,N){return o?.entry?.task??o?.label??o?.command?.join(" ")??N.workloadId}function sn(o){let N=new Map(o.workloads.map((v)=>[v.id,v])),c=o.runs.filter((v)=>v.phase==="timing"&&v.timing!==void 0).map((v)=>({run:v,workload:N.get(v.workloadId)})),I=c.length>1?ue(c):void 0,m=new Map((o.comparisons??[]).map((v)=>[v.candidateRunId,v]));return c.map((v)=>{let{run:C,workload:P}=v,U=C.timing,D={task:rn(P,C),unit:"ns",samples:U.samples.length,mean:X(U.mean),median:X(U.median),stddev:X(U.stddev),stddevPct:X(U.mean===0?0:U.stddev/U.mean*100),min:X(U.min),max:X(U.max),warnings:C.warnings.map((O)=>O.data?{code:O.code,data:O.data}:{code:O.code})};if(P?.entry?.group!==void 0)D.group=P.entry.group;if(P?.description!==void 0)D.description=P.description;if(P?.groupDescription!==void 0)D.groupDescription=P.groupDescription;if(I)D.relative=X(U.median/(I.get(v)??U.median));if(P?.baseline)D.baseline=!0;let M=m.get(C.id);if(M?.timing)D.delta={medianPct:X(M.timing.medianDeltaPct),meanPct:X(M.timing.meanDeltaPct),verdict:M.timing.verdict,pass:M.verdict==="pass"};return D})}var Me={name:"minimal",async render(o){let N=sn(o).map((c)=>JSON.stringify(c));return{text:N.length>0?`${N.join(`
|
|
13
|
+
`)}
|
|
14
|
+
`:""}}};var on="https://www.speedscope.app/file-format-schema.json";function Se(o){return o?.label??o?.command?.join(" ")??o?.entry?.task??"profile"}var Be={name:"speedscope",async render(o,N={}){let c=ee(o,N.runId),I=new Map(o.workloads.map((v)=>[v.id,v]));return{files:c.map((v)=>{let C=v.cpu,{nodes:P}=C,U=se(C),D=C.samples?.nodeIds??[],M=C.samples?.timeDeltasUs??[],O=Array(U.count);for(let _ of U.order){let J=U.parentIx[_],V=P[_].frameIx;O[_]=J===-1?[V]:[...O[J],V]}let A=Array(D.length);for(let _=0;_<D.length;_++){let J=U.indexOf(D[_]);A[_]=J===-1?[]:O[J]}let z=0;for(let _=0;_<M.length;_++)z+=M[_];let K={$schema:on,exporter:"ostia",name:Se(I.get(v.workloadId)),activeProfileIndex:0,shared:{frames:C.frames.map((_)=>({name:_.name||"(anonymous)",file:_.url,line:_.line!==void 0?_.line+1:void 0}))},profiles:[{type:"sampled",name:Se(I.get(v.workloadId)),unit:"microseconds",startValue:0,endValue:z,samples:A,weights:M}]};return{path:`${v.id}.speedscope.json`,content:`${JSON.stringify(K,null,2)}
|
|
15
|
+
`}})}}};function oe(o){return(o/1e6).toFixed(3)}function me(o){return o.label??o.command?.join(" ")??o.entry?.task??o.id}var We={name:"table",async render(o){let N=o.runs.filter((O)=>O.phase==="timing"&&O.timing!==void 0),c=new Map(o.workloads.map((O)=>[O.id,O]));if(N.length===0){let O=Oe(o,c);return{text:O.length>0?`${O.join(`
|
|
16
|
+
`)}
|
|
17
|
+
`:`(no timing runs)
|
|
18
|
+
`}}let I=N.map((O)=>{let A=c.get(O.workloadId);return{run:O,workload:A,label:A?me(A):O.workloadId}}),m=I.length>1,v=ue(I),C=[],P=Math.max(7,...I.map((O)=>O.label.length)),U=m?`${"Command".padEnd(P)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(P)} Mean [ms] Min\u2026Max [ms]`;C.push(U),C.push("-".repeat(U.length));for(let O of I){let{run:A,label:z,workload:K}=O,_=A.timing,J=`${oe(_.mean)} \xB1 ${oe(_.stddev)}`,V=`${oe(_.min)}\u2026${oe(_.max)}`,L=`${z.padEnd(P)} ${J.padEnd(15)} ${V.padEnd(18)}`;if(m){let j=_.median/(v.get(O)??_.median);if(j===1)L+=K?.baseline?" 1.00\xD7 (baseline)":" 1.00\xD7";else if(j>1)L+=` ${j.toFixed(2)}\xD7 slower`;else L+=` ${(1/j).toFixed(2)}\xD7 faster`}C.push(L);for(let j of A.warnings)C.push(` ! ${j.message}`)}let D=cn(o,c);if(D.length>0)C.push(""),C.push(...D);let M=Oe(o,c);if(M.length>0)C.push(""),C.push(...M);return{text:`${C.join(`
|
|
19
|
+
`)}
|
|
20
|
+
`}}};function an(o,N,c){let I=o.runs.find((v)=>v.id===c),m=I?N.get(I.workloadId):void 0;return m?me(m):c}function Oe(o,N){if(!o.comparisons||o.comparisons.length===0)return[];let c=[];for(let I of o.comparisons){let m=an(o,N,I.candidateRunId),v=I.verdict==="pass"?"\u2713":"\u2717";if(c.push(`${v} ${m}`),I.timing){let C=I.timing.medianDeltaPct>0?"+":"";c.push(` timing: ${C}${I.timing.medianDeltaPct.toFixed(1)}% median (${I.timing.verdict})`)}if(I.frames)for(let C of I.frames.slice(0,Ee)){if(Math.abs(C.deltaPct)<0.5)continue;let P=C.deltaPct>0?"+":"";c.push(` frame ${C.name}: ${P}${C.deltaPct.toFixed(1)}% self-time (${(C.baseSelfUs/1000).toFixed(2)}ms -> ${(C.candSelfUs/1000).toFixed(2)}ms)`)}if(I.heapTypes)for(let C of I.heapTypes.slice(0,Ae)){if(Math.abs(C.deltaPct)<0.5)continue;let P=C.deltaPct>0?"+":"";c.push(` heap ${C.type}: ${P}${C.deltaPct.toFixed(1)}% count (${C.baseCount} -> ${C.candCount})`)}}return c}var Ee=5,Ae=5;function cn(o,N){let c=[];for(let I of o.runs){if(I.phase!=="cpu"&&I.phase!=="heap")continue;let m=N.get(I.workloadId),v=m?me(m):I.workloadId;if(I.phase==="cpu")if(I.cpu){c.push(`CPU capture - ${v} (instrumented, ${I.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${oe(I.diagnosticWallNs??0)}ms)`);let C=I.cpu.totals.reduce((P,U)=>P+U.selfUs,0)||1;for(let P of I.cpu.totals.slice(0,Ee)){let U=I.cpu.frames[P.frameIx],D=(P.selfUs/C*100).toFixed(1);c.push(` ${D.padStart(5)}% ${(P.selfUs/1000).toFixed(2).padStart(8)}ms self ${U?.name??"?"}`)}}else c.push(`CPU capture - ${v} (instrumented, no evidence captured)`);else if(I.heap){let C=((I.heap.heapSizeBytes??0)/1e6).toFixed(2);c.push(`Heap snapshot - ${v} (instrumented, ${I.heap.objectCount??"?"} objects, ${C}MB)`);for(let P of I.heap.typeCounts.slice(0,Ae))c.push(` ${String(P.count).padStart(6)} ${P.type}`)}else c.push(`Heap snapshot - ${v} (instrumented, no evidence captured)`);for(let C of I.artifacts)c.push(` artifact: ${C.path}`);for(let C of I.warnings)c.push(` ! ${C.message}`)}return c}var n={table:We,json:$e,markdown:Ue,jsonl:ve,minimal:Me,collapsed:Te,mermaid:De,speedscope:Be,cpuprofile:Ie};var un="node_modules/.cache/ostia",de=1000;async function y(o){let N=s({runs:o.runs??null,warmup:o.warmup??null,cpu:o.cpu??!1,heap:o.heap??!1,cpuIntervalUs:o.cpuIntervalUs??de}),I=`${o.outDir??un}/artifacts`,m=[],v=[];for(let C of o.commands){let P=Array.isArray(C)?C:Re(C),U=u(P,Array.isArray(C)?void 0:C);m.push(U);let D=await g({argv:P,cwd:o.cwd,env:o.env,runs:o.runs,warmup:o.warmup}),M=i({workload:U,configFingerprint:N,trials:D.trials,timing:D.timing,warnings:D.warnings});if(v.push(M),o.cpu){let O=`${M.id}-cpu.cpuprofile`,A=await fe({argv:P,cwd:o.cwd,env:o.env,artifactDir:I,fileName:O,intervalUs:o.cpuIntervalUs??de});v.push(await je({workload:U,phase:"cpu",configFingerprint:N,diagnosticWallNs:A.diagnosticWallNs,exitCode:A.exitCode,cpu:A.cpu,artifactPath:A.artifactPath,artifactKind:"cpuprofile",warnings:A.warnings}))}if(o.heap){let O=`${M.id}-heap.heapsnapshot`,A=await he({argv:P,cwd:o.cwd,env:o.env,artifactDir:I,fileName:O});v.push(await je({workload:U,phase:"heap",configFingerprint:N,diagnosticWallNs:A.diagnosticWallNs,exitCode:A.exitCode,heap:A.heap,artifactPath:A.artifactPath,artifactKind:"heapsnapshot",warnings:A.warnings}))}}return r(m,v)}async function je(o){let N=`${o.workload.id}-${o.phase}-${o.configFingerprint}`,c=o.artifactPath?[await T(N,o.artifactKind,o.artifactPath)]:[];return b({workload:o.workload,phase:o.phase,configFingerprint:o.configFingerprint,diagnosticWallNs:o.diagnosticWallNs,exitCode:o.exitCode,cpu:o.cpu,heap:o.heap,warnings:o.warnings,artifacts:c})}async function S(o,N={}){let c=R(o),I=s({intervalUs:N.intervalUs??de,origin:N.origin??"inspector"}),m=(D)=>D.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(N.origin==="jsc"){let{result:D,cpu:M,jit:O,diagnosticWallNs:A}=await xe(o,N),z=b({workload:c,phase:"cpu",configFingerprint:I,diagnosticWallNs:A,cpu:M,jit:O,warnings:m(M),artifacts:[]});return{result:D,run:z}}let{result:v,cpu:C,diagnosticWallNs:P}=await be(o,N),U=b({workload:c,phase:"cpu",configFingerprint:I,diagnosticWallNs:P,cpu:C,warnings:m(C),artifacts:[]});return{result:v,run:U}}
|
|
21
|
+
export{x,d,a,f,w,g,F,n,y,S};
|
package/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{x,d,a,f,w,g,n,y}from"./chunk-
|
|
4
|
-
`)}var X="node_modules/.cache/ostia",Q=".ostia/baselines",Y={runs:null,warmup:3,outDir:X,baselineDir:Q,baseline:"main",cpuIntervalUs:1000,thresholds:a,workloads:[]};async function
|
|
3
|
+
import{x,d,a,f,w,g,n,y}from"./chunk-tw064qem.js";import{e,c,r,u,i,s,o,t}from"./chunk-nfgy545q.js";function q(p){return e("cache",p.workloadId,p.phase,p.configFingerprint,p.bunVersion,p.toolVersion,p.instrumented,p.inputsDigest??null)}async function _(p,l=process.cwd()){if(p.length===0)return;let m=new Set;for(let b of p){let P=new Bun.Glob(b);for await(let C of P.scan({cwd:l,absolute:!1}))m.add(C)}let k=[...m].sort(),h=await Promise.all(k.map(async(b)=>{let P=await Bun.file(`${l}/${b}`).arrayBuffer();return{path:b,sha256:Bun.CryptoHasher.hash("sha256",P,"hex")}}));return e("inputs",h)}function L(p,l){return`${p}/cache/${l}.json`}async function M(p,l){let m=Bun.file(L(p,l));if(!await m.exists())return;return await m.json()}async function z(p,l,m){await Bun.write(L(p,l),`${JSON.stringify(m,null,2)}
|
|
4
|
+
`)}var X="node_modules/.cache/ostia",Q=".ostia/baselines",Y={runs:null,warmup:3,outDir:X,baselineDir:Q,baseline:"main",cpuIntervalUs:1000,thresholds:a,workloads:[]};async function W(p="ostia.config.json"){let l=Bun.file(p);if(!await l.exists())return;let m=await l.json();return{...Y,...m,thresholds:{...a,...m.thresholds??{}}}}function V(p,l){return`${p.baselineDir}/${l??p.baseline}.json`}class B extends Error{path;constructor(p){super(`No baseline document at ${p}. Create one with: ostia run --export-json ${p} <command...>`);this.path=p}}async function K(p){let{config:l}=p,m=V(l,p.baselineName);if(!await Bun.file(m).exists())throw new B(m);let h=await t(m),b=[],P=0,C=0,F=0;for(let j of l.workloads){let R=u(j.command,j.label),S=await _(j.inputs??[]),I=s({runs:l.runs,warmup:l.warmup}),H=q({workloadId:R.id,phase:"timing",configFingerprint:I,bunVersion:Bun.version,toolVersion:c,instrumented:!1,inputsDigest:S}),J=p.full?void 0:await M(l.outDir,H),T,O;if(J)T=J,O="cached",C++;else{P++;let U=await g({argv:j.command,runs:l.runs??void 0,warmup:l.warmup});T=i({workload:R,configFingerprint:I,trials:U.trials,timing:U.timing,warnings:U.warnings}),await z(l.outDir,H,T),O="executed",F++}b.push({workload:R,status:O,run:T})}let D=r(b.map((j)=>j.workload),b.map((j)=>j.run)),A=0,E=0,N=0;for(let j of b){let R=w(h,D,j.workload.id,l.thresholds);if(!R){N++;continue}if(j.comparison=R,R.verdict==="pass")A++;else E++}return D.comparisons=b.map((j)=>j.comparison).filter((j)=>j!==void 0),{document:D,summary:{total:l.workloads.length,affected:P,cached:C,executed:F,passed:A,regressed:E,missingBaseline:N,results:b}}}function G(p){let l=[];if(l.push(`${p.total} workloads`),l.push(`${p.affected} affected by this change`),l.push(`${p.cached} cached`),l.push(`${p.executed} executed`),p.missingBaseline>0)l.push(`${p.missingBaseline} skipped (no matching baseline workload)`);let m=p.results.filter((k)=>k.comparison?.verdict==="fail").map((k)=>{let h=k.comparison.timing,b=k.workload.label??k.workload.command?.join(" ")??k.workload.id;return h?`${h.medianDeltaPct>0?"+":""}${h.medianDeltaPct.toFixed(1)}% median on ${b}`:b});return l.push(`${p.passed} passed ${p.regressed} regressed${m.length>0?` (${m.join(", ")})`:""}`),l.push(""),l.push(`Profile CI: ${p.regressed>0?"\u2717":"\u2713"}`),`${l.join(`
|
|
5
5
|
`)}
|
|
6
|
-
`}async function
|
|
6
|
+
`}async function v(p,l){if(p.text)process.stdout.write(p.text);if(!p.files||p.files.length===0)return;if(l)for(let m of p.files){let k=m.path?`${l}/${m.path}`:l;await Bun.write(k,m.content),process.stdout.write(`wrote ${k}
|
|
7
7
|
`)}else if(p.files.length===1)process.stdout.write(p.files[0].content);else for(let m of p.files)process.stdout.write(`--- ${m.path??"(unnamed)"} ---
|
|
8
8
|
${m.content}
|
|
9
9
|
`)}var ee=`ostia run [flags] <command...>
|
|
@@ -49,7 +49,8 @@ Flags:
|
|
|
49
49
|
Concurrent CPU-bound processes contend for cores, caches and turbo
|
|
50
50
|
headroom, so numbers taken at --jobs > 1 are noisier and not
|
|
51
51
|
like-for-like with a baseline measured at 1. "auto" = CPU count.
|
|
52
|
-
--gc Bun.gc(true) between trials (default: off - hides allocation cost)
|
|
52
|
+
--gc Bun.gc(true) between trials (default: off - hides allocation cost).
|
|
53
|
+
Per-task { gc } / per-group { gc } override this default.
|
|
53
54
|
--filter REGEX only run tasks whose "group/name" id matches this regex (substring,
|
|
54
55
|
case-sensitive; unmatched tasks are skipped, not timed)
|
|
55
56
|
--isolate give every task its own subprocess instead of sharing its suite
|
|
@@ -59,6 +60,10 @@ Flags:
|
|
|
59
60
|
--jobs then pools across those per-task processes, so pair a
|
|
60
61
|
higher --jobs with --isolate deliberately: overhead now scales
|
|
61
62
|
with task count, not file count.
|
|
63
|
+
--preload PATH script imported before each suite file loads, in the same
|
|
64
|
+
subprocess (repeatable; runs in the order given). Use it to
|
|
65
|
+
install globals (jsdom's document/window) or register a
|
|
66
|
+
Bun.plugin() file-loader before the suite's own code runs.
|
|
62
67
|
--out-dir PATH directory for scratch IPC files (default: node_modules/.cache/ostia)
|
|
63
68
|
--export-json PATH write the full ProfileDocument to PATH
|
|
64
69
|
--format FORMAT table | json | jsonl | markdown | minimal (default: table)
|
|
@@ -75,15 +80,27 @@ Suite files register tasks like:
|
|
|
75
80
|
task("small input", () => parse(smallBuf))
|
|
76
81
|
task("full pipeline", () => build(), { timeBudgetMs: 2000, minSamples: 10 })
|
|
77
82
|
}, { description: "parser throughput on representative inputs" })
|
|
78
|
-
Per-task options override --time-budget / --min-samples for that task
|
|
83
|
+
Per-task options override --time-budget / --min-samples / --gc / --isolate for that task
|
|
84
|
+
only; per-group { gc } / { isolate } set the default for every task in that group.
|
|
79
85
|
Optional { description } on group() and task() flows into the document (Workload.description
|
|
80
86
|
/ Workload.groupDescription) so the intent travels with the numbers.
|
|
81
87
|
|
|
88
|
+
Sweep a size dimension with range(start, end, multiplier?) (mitata's .range() point
|
|
89
|
+
generation, default multiplier 8, always ending on the end value):
|
|
90
|
+
import { group, task, range } from "<pkg>"
|
|
91
|
+
group("parse", () => {
|
|
92
|
+
for (const size of range(100, 10_000)) {
|
|
93
|
+
const input = buildInput(size) // setup, runs once per point, unmeasured
|
|
94
|
+
task(\`\${size} items\`, () => parse(input))
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
|
|
82
98
|
Examples:
|
|
83
99
|
ostia bench benches/parse.ts
|
|
84
100
|
ostia bench --time-budget 1000 --min-samples 50 benches/*.ts
|
|
85
101
|
ostia bench benches/*.ts --filter parse
|
|
86
102
|
ostia bench benches/*.ts --jobs auto --format minimal
|
|
103
|
+
ostia bench --preload ./bench/jsdom-setup.ts benches/*.dom.bench.ts
|
|
87
104
|
`,Z=`ostia compare <base.json> <candidate.json>
|
|
88
105
|
ostia compare <candidate.json> --baseline <path.json>
|
|
89
106
|
|
|
@@ -136,20 +153,20 @@ Flags:
|
|
|
136
153
|
--help show this message
|
|
137
154
|
|
|
138
155
|
Exit codes: 0 pass, 1 regression, 2 harness error (missing config/baseline, spawn failure).
|
|
139
|
-
`;function oe(p){let l=[],m,k,h=!1,b=!1,P,
|
|
156
|
+
`;function oe(p){let l=[],m,k,h=!1,b=!1,P,C,F,D="table",A=!1,E=!1;for(let N=0;N<p.length;N++){let j=p[N];switch(j){case"--runs":m=Number(p[++N]);break;case"--warmup":k=Number(p[++N]);break;case"--cpu":h=!0;break;case"--heap":b=!0;break;case"--cpu-interval":P=Number(p[++N]);break;case"--out-dir":C=p[++N];break;case"--export-json":F=p[++N];break;case"--format":D=p[++N];break;case"--quiet":A=!0;break;case"--help":case"-h":E=!0;break;default:l.push(j)}}return{commands:l,runs:m,warmup:k,cpu:h,heap:b,cpuIntervalUs:P,outDir:C,exportJson:F,format:D,quiet:A,help:E}}async function ae(p){let l=oe(p);if(l.help||l.commands.length===0)return process.stdout.write(ee),l.help?0:2;if(!(l.format in n))return process.stderr.write(`Unknown --format "${l.format}". Expected one of: ${Object.keys(n).join(", ")}
|
|
140
157
|
`),2;let m;try{m=await y({commands:l.commands,runs:l.runs,warmup:l.warmup,cpu:l.cpu,heap:l.heap,cpuIntervalUs:l.cpuIntervalUs,outDir:l.outDir})}catch(h){return process.stderr.write(`Run failed: ${h instanceof Error?h.message:String(h)}
|
|
141
|
-
`),2}if(l.exportJson)await o(m,l.exportJson);if(!l.quiet){let b=await n[l.format].render(m,{});await
|
|
158
|
+
`),2}if(l.exportJson)await o(m,l.exportJson);if(!l.quiet){let b=await n[l.format].render(m,{});await v(b)}return m.runs.some((h)=>h.trials.some((b)=>b.exitCode!==void 0&&b.exitCode!==0))?1:0}function ie(p){let l=[],m,k,h,b=!1,P,C=!1,F=[],D,A,E="table",N=!1,j=!1;for(let R=0;R<p.length;R++){let S=p[R];switch(S){case"--time-budget":m=Number(p[++R]);break;case"--min-samples":k=Number(p[++R]);break;case"--jobs":{let I=p[++R];h=I==="auto"?x():Number(I);break}case"--gc":b=!0;break;case"--filter":P=p[++R];break;case"--isolate":C=!0;break;case"--preload":F.push(p[++R]);break;case"--out-dir":D=p[++R];break;case"--export-json":A=p[++R];break;case"--format":E=p[++R];break;case"--quiet":N=!0;break;case"--help":case"-h":j=!0;break;default:l.push(S)}}return{suites:l,timeBudgetMs:m,minSamples:k,jobs:h,gc:b,filter:P,isolate:C,preload:F,outDir:D,exportJson:A,format:E,quiet:N,help:j}}async function ue(p){let l=ie(p);if(l.help||l.suites.length===0)return process.stdout.write(te),l.help?0:2;if(!(l.format in n))return process.stderr.write(`Unknown --format "${l.format}". Expected one of: ${Object.keys(n).join(", ")}
|
|
142
159
|
`),2;if(l.jobs!==void 0&&!(l.jobs>=1))return process.stderr.write(`--jobs expects a positive integer or "auto".
|
|
143
|
-
`),2;let m;try{m=await d({suites:l.suites,timeBudgetMs:l.timeBudgetMs,minSamples:l.minSamples,jobs:l.jobs,gc:l.gc,filter:l.filter,isolate:l.isolate,outDir:l.outDir})}catch(k){return process.stderr.write(`Bench failed: ${k instanceof Error?k.message:String(k)}
|
|
144
|
-
`),2}if(l.exportJson)await o(m,l.exportJson);if(!l.quiet){let h=await n[l.format].render(m,{});await
|
|
145
|
-
`),2}let P=f(h,b),
|
|
146
|
-
`),2}let h=await n[l.format].render(m,{});return await
|
|
160
|
+
`),2;let m;try{m=await d({suites:l.suites,timeBudgetMs:l.timeBudgetMs,minSamples:l.minSamples,jobs:l.jobs,gc:l.gc,filter:l.filter,isolate:l.isolate,preload:l.preload,outDir:l.outDir})}catch(k){return process.stderr.write(`Bench failed: ${k instanceof Error?k.message:String(k)}
|
|
161
|
+
`),2}if(l.exportJson)await o(m,l.exportJson);if(!l.quiet){let h=await n[l.format].render(m,{});await v(h)}return 0}function le(p){let l=[],m,k,h="table",b=!1,P=!1;for(let C=0;C<p.length;C++){let F=p[C];switch(F){case"--baseline":m=p[++C];break;case"--export-json":k=p[++C];break;case"--format":h=p[++C];break;case"--quiet":b=!0;break;case"--help":case"-h":P=!0;break;default:l.push(F)}}return{paths:l,baseline:m,exportJson:k,format:h,quiet:b,help:P}}async function ce(p){let l=le(p);if(l.help)return process.stdout.write(Z),0;let m,k;if(l.baseline)m=l.baseline,k=l.paths[0];else m=l.paths[0],k=l.paths[1];if(!m||!k)return process.stdout.write(Z),2;let h,b;try{[h,b]=await Promise.all([t(m),t(k)])}catch(D){return process.stderr.write(`Failed to load documents: ${D instanceof Error?D.message:String(D)}
|
|
162
|
+
`),2}let P=f(h,b),C={...b,comparisons:P};if(l.exportJson)await o(C,l.exportJson);if(!l.quiet){let A=await n[l.format].render(C,{});await v(A)}return P.some((D)=>D.verdict==="fail")?1:0}function de(p){let l,m="table",k=!1;for(let h=0;h<p.length;h++){let b=p[h];switch(b){case"--format":m=p[++h];break;case"--help":case"-h":k=!0;break;default:l=b}}return{path:l,format:m,help:k}}async function pe(p){let l=de(p);if(l.help||!l.path)return process.stdout.write(re),l.help?0:2;let m;try{m=await t(l.path)}catch(b){return process.stderr.write(`Failed to load ${l.path}: ${b instanceof Error?b.message:String(b)}
|
|
163
|
+
`),2}let h=await n[l.format].render(m,{});return await v(h),0}var me={ascii:"table"};function fe(p){let l,m,k,h,b=!1;for(let P=0;P<p.length;P++){let C=p[P];switch(C){case"--format":{let F=p[++P]??"";m=me[F]??F;break}case"--run":k=p[++P];break;case"--out-dir":h=p[++P];break;case"--help":case"-h":b=!0;break;default:l=C}}return{path:l,format:m,runId:k,outDir:h,help:b}}async function he(p){let l=fe(p);if(l.help||!l.path||!l.format)return process.stdout.write(se),l.help?0:2;if(!(l.format in n))return process.stderr.write(`Unknown --format "${l.format}". Expected one of: ${Object.keys(n).join(", ")}, ascii
|
|
147
164
|
`),2;let m;try{m=await t(l.path)}catch(b){return process.stderr.write(`Failed to load ${l.path}: ${b instanceof Error?b.message:String(b)}
|
|
148
165
|
`),2}let h=await n[l.format].render(m,{runId:l.runId});if(!h.text&&(!h.files||h.files.length===0))return process.stderr.write(l.runId?`No CPU evidence found for run "${l.runId}".
|
|
149
166
|
`:`No CPU evidence found in this document (no cpu-phase runs). Capture some with "ostia run --cpu ...".
|
|
150
|
-
`),2;return await
|
|
167
|
+
`),2;return await v(h,l.outDir),0}function ge(p){let l=!1,m,k,h=!1,b=!1;for(let P=0;P<p.length;P++)switch(p[P]){case"--full":l=!0;break;case"--baseline":m=p[++P];break;case"--export-json":k=p[++P];break;case"--quiet":h=!0;break;case"--help":case"-h":b=!0;break}return{full:l,baseline:m,exportJson:k,quiet:h,help:b}}async function be(p){let l=ge(p);if(l.help)return process.stdout.write(ne),0;let m=await W();if(!m)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
|
|
151
168
|
`),2;if(m.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
|
|
152
|
-
`),2;let k;try{k=await K({config:m,full:l.full,baselineName:l.baseline})}catch(h){if(h instanceof
|
|
169
|
+
`),2;let k;try{k=await K({config:m,full:l.full,baselineName:l.baseline})}catch(h){if(h instanceof B)return process.stderr.write(`${h.message}
|
|
153
170
|
`),2;return process.stderr.write(`CI run failed: ${h instanceof Error?h.message:String(h)}
|
|
154
171
|
`),2}if(l.exportJson)await o(k.document,l.exportJson);if(!l.quiet)process.stdout.write(G(k.summary));return k.summary.regressed>0?1:0}async function we(){let[p,...l]=process.argv.slice(2);switch(p){case"run":return ae(l);case"bench":return ue(l);case"compare":return ce(l);case"report":return pe(l);case"ci":return be(l);case"viz":return he(l);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
|
|
155
172
|
|
package/index.d.ts
CHANGED
|
@@ -257,10 +257,18 @@ interface BenchOptions {
|
|
|
257
257
|
* many cheap ones sharing a process). Multiplies process-spawn overhead by
|
|
258
258
|
* task count instead of file count. */
|
|
259
259
|
isolate?: boolean;
|
|
260
|
+
/** Scripts run, in order, before each suite file loads - in the same
|
|
261
|
+
* subprocess, so they can install globals (jsdom's `document`/`window`) or
|
|
262
|
+
* register a `Bun.plugin()` file-loader (e.g. for `.svelte`/`.vue`) ahead
|
|
263
|
+
* of the suite's own top-level code. Consumer-authored; ostia ships no
|
|
264
|
+
* preload scripts itself. */
|
|
265
|
+
preload?: string[];
|
|
260
266
|
}
|
|
261
267
|
|
|
262
268
|
export declare function bench(opts: BenchOptions): Promise<ProfileDocument>;
|
|
263
269
|
|
|
270
|
+
export declare function range(start: number, end: number, multiplier?: number): number[];
|
|
271
|
+
|
|
264
272
|
export interface TaskOptions {
|
|
265
273
|
/** Marks this task as the Relative reference for its group in the table
|
|
266
274
|
* renderer, mirroring mitata's `baseline()`. At most one per group. */
|
|
@@ -278,6 +286,9 @@ export interface TaskOptions {
|
|
|
278
286
|
* run. Overrides the group's and the suite-wide `bench({ isolate })` /
|
|
279
287
|
* `--isolate` default for this task only. */
|
|
280
288
|
isolate?: boolean;
|
|
289
|
+
/** Overrides the suite-wide `bench({ gc })` / `--gc` (and any
|
|
290
|
+
* `GroupOptions.gc`) for this task only. */
|
|
291
|
+
gc?: boolean;
|
|
281
292
|
}
|
|
282
293
|
|
|
283
294
|
export interface GroupOptions {
|
|
@@ -287,6 +298,9 @@ export interface GroupOptions {
|
|
|
287
298
|
/** Default `isolate` for every task in this group, unless a task overrides
|
|
288
299
|
* it with its own `TaskOptions.isolate`. */
|
|
289
300
|
isolate?: boolean;
|
|
301
|
+
/** Default `gc` for every task in this group, unless a task overrides it
|
|
302
|
+
* with its own `TaskOptions.gc`. */
|
|
303
|
+
gc?: boolean;
|
|
290
304
|
}
|
|
291
305
|
|
|
292
306
|
export declare function group(name: string, fn: () => void, opts?: GroupOptions): void;
|
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{d,f,n,y,
|
|
2
|
+
import{d,f,F,n,y,S}from"./chunk-tw064qem.js";import{o,t,U,M}from"./chunk-nfgy545q.js";export{d as bench,f as compareDocuments,U as group,t as loadDocument,S as profile,F as range,n as renderers,y as run,o as saveDocument,M as task};
|
package/package.json
CHANGED
package/runner.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{r,P,i,s,o,l,
|
|
4
|
-
`),2;let
|
|
5
|
-
`),2;let f=
|
|
6
|
-
`),2;if(
|
|
3
|
+
import{r,P,i,s,o,l,p,I,C,m,N,D,v}from"./chunk-nfgy545q.js";var z=500,H=20,A=3,j=10,X=2,q=0.1,K=1000,Q=1e4;function J(n){let e=Math.log10(Math.max(1,n)/1e6),a=Math.round(A+X*e);return Math.min(j,Math.max(A,a))}function V(n,e){let a=Math.floor(e/n);return Math.min(H,Math.max(a,J(n)))}var L=0;function O(n){if(typeof n==="number")L+=n;else if(n!==void 0&&n!==null)L+=1}function B(n){return n!==null&&typeof n==="object"&&typeof n.then==="function"}function G(n,e){return Math.max(1,Math.ceil(K/n),Math.ceil(e/(n*Q)))}async function U(n,e={}){let a=(e.timeBudgetMs??z)*1e6,u=a*(e.warmupFraction??q),T=Bun.nanoseconds(),f=0,b=0;while(b<u){let d=n();O(B(d)?await d:d),f++,b=Bun.nanoseconds()-T}let h;if(f>0)h=Math.max(1,b/f);else{let d=Bun.nanoseconds(),w=n();O(B(w)?await w:w),h=Math.max(1,Bun.nanoseconds()-d)}let t=G(h,a);if(t>1){let d=Bun.nanoseconds();for(let w=0;w<t;w++){let k=n();O(B(k)?await k:k)}h=Math.max(1,(Bun.nanoseconds()-d)/t),t=G(h,a)}let c=h*t,S=e.minSamples??V(c,a),g=[],M=Bun.nanoseconds(),_=0,R=0;while(R<S||_<a){let d=Bun.nanoseconds();for(let k=0;k<t;k++){let F=n();O(B(F)?await F:F)}let w=Bun.nanoseconds();if(g.push({i:R,wallNs:(w-d)/t}),R++,_=Bun.nanoseconds()-M,e.gc)Bun.gc(!0)}let W=g.map((d)=>d.wallNs),y=l(W),E=p(y,[],"inprocess"),x=J(c);if(g.length<x)E.push({code:"low-sample-count",message:`Only ${g.length} sample(s) at ~${Y(c)} per trial; ${x} is the floor for this cost class. Raise minSamples or the time budget for a steadier number.`,data:{samples:g.length,target:x,trialCostNs:c}});return{trials:g,timing:y,warnings:E}}function Y(n){if(n>=1e9)return`${(n/1e9).toFixed(2)}s`;if(n>=1e6)return`${(n/1e6).toFixed(1)}ms`;if(n>=1000)return`${(n/1000).toFixed(1)}\xB5s`;return`${n.toFixed(0)}ns`}async function Z(){let[n,e,a]=process.argv.slice(2);if(!n||!e)return process.stderr.write(`bench runner: usage: runner.ts <suiteFile> <outputPath> [optsJson]
|
|
4
|
+
`),2;let u=a?JSON.parse(a):{};for(let t of u.preload??[])await import(t);C(),await import(n);let T=I();if(T.length===0)return process.stderr.write(`bench runner: ${n} registered no tasks (no task() calls found).
|
|
5
|
+
`),2;let f=v(T,u.filter);if(u.taskIds){let t=new Set(u.taskIds);f=f.filter((c)=>t.has(m(c)))}if(f.length===0)return process.stderr.write(`bench runner: --filter ${JSON.stringify(u.filter)} matched zero of ${T.length} registered tasks in ${n}.
|
|
6
|
+
`),2;if(u.planOnly){let t=f.map((c)=>({id:m(c),isolate:N(c,u.isolate??!1)}));return await Bun.write(e,JSON.stringify({tasks:t})),0}let b=[],h=[];for(let t of f){let c=m(t),S=P(n,c,{label:c,baseline:t.baseline,group:t.groupName,description:t.opts?.description,groupDescription:t.groupDescription,isolated:u.markIsolated});b.push(S);let g={...u,...t.opts?.timeBudgetMs!==void 0&&{timeBudgetMs:t.opts.timeBudgetMs},...t.opts?.minSamples!==void 0&&{minSamples:t.opts.minSamples},gc:D(t,u.gc??!1)},M=await U(t.fn,g);h.push(i({workload:S,configFingerprint:s({timeBudgetMs:g.timeBudgetMs??null,minSamples:g.minSamples??null,gc:g.gc??!1}),trials:M.trials,timing:M.timing,warnings:M.warnings}))}return await o(r(b,h),e),0}Z().then((n)=>process.exit(n));
|
package/chunk-gsjgejr1.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{h,e,r,u,R,i,b,T,s,k,t,l,m}from"./chunk-y1gkhb0y.js";function je(o){return o.startsWith("file://")?o.slice(7):o}function oe(o,D,c){let C=o.nodes,p=C.length,I=new Map,N=[],P=new Map,U=new Int32Array(p);for(let O=0;O<p;O++){let W=C[O],F=W.callFrame,L=je(F.url),K=I.get(F.functionName);if(K===void 0)K=new Map,I.set(F.functionName,K);let G=K.get(L);if(G===void 0)G=N.length,K.set(L,G),N.push({key:e("fr",F.functionName,L),name:F.functionName,url:L||void 0,line:F.lineNumber>=0?F.lineNumber:void 0,col:F.columnNumber>=0?F.columnNumber:void 0});U[O]=G,P.set(W.id,O)}let B=Array(p);for(let O=0;O<p;O++){let W=C[O];B[O]={id:W.id,frameIx:U[P.get(W.id)],children:W.children??[]}}let M=new Float64Array(p),S=new Float64Array(p),{samples:E,timeDeltas:V}=o;for(let O=0;O<E.length;O++){let W=P.get(E[O]);if(W===void 0)continue;M[W]+=V[O]??0,S[W]+=1}let z=new Int32Array(p).fill(-1);for(let O=0;O<p;O++){let W=C[O].children;if(!W)continue;for(let F of W){let L=P.get(F);if(L!==void 0)z[L]=O}}let A=[],H=[];for(let O=p-1;O>=0;O--)if(z[O]===-1)H.push(O);while(H.length>0){let O=H.pop();A.push(O);let W=C[O].children;if(!W)continue;for(let F of W){let L=P.get(F);if(L!==void 0&&z[L]===O)H.push(L)}}let _=new Float64Array(p);for(let O=A.length-1;O>=0;O--){let W=A[O];_[W]+=M[W];let F=z[W];if(F>=0)_[F]+=_[W]}let J=Array(N.length),j=[];for(let O=0;O<p;O++){let W=B[O].frameIx,F=J[W];if(F)F.selfUs+=M[O],F.totalUs+=_[O],F.samples+=S[O];else{let L={frameIx:W,selfUs:M[O],totalUs:_[O],samples:S[O]};J[W]=L,j.push(L)}}return{origin:D,samplingIntervalUs:c,frames:N,nodes:B,totals:j.sort((O,W)=>W.selfUs-O.selfUs),samples:{nodeIds:o.samples,timeDeltasUs:o.timeDeltas}}}function _e(o,D,c,C){let p=["--cpu-prof","--cpu-prof-dir",D,"--cpu-prof-name",c,"--cpu-prof-interval",String(C)],I=o[0];if(I==="bun"||I?.endsWith("/bun"))return[I,...p,...o.slice(1)];return o}async function de(o){let D=`${o.artifactDir}/${o.fileName}`,c=o.argv[0],C=c==="bun"||c?.endsWith("/bun"),p=_e(o.argv,o.artifactDir,o.fileName,o.intervalUs),I=C?o.env:{...process.env,...o.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${o.artifactDir} --cpu-prof-name ${o.fileName} --cpu-prof-interval ${o.intervalUs}`},N=Bun.nanoseconds(),U=await Bun.spawn(p,{cwd:o.cwd,env:I,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,B=Bun.nanoseconds()-N,M=Bun.file(D);if(!await M.exists())return{diagnosticWallNs:B,exitCode:U,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${D} after exit ${U}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:D,argv:o.argv}}]};let S=await M.json(),E=oe(S,"cpu-prof",o.intervalUs),V=S.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:B,exitCode:U,artifactPath:D,cpu:E,warnings:V}}function fe(o,D="heap-prof"){let{node_fields:c,node_types:C}=o.snapshot.meta,p=c.indexOf("type"),I=c.indexOf("self_size"),N=c.length,P=C[0];if(p===-1||I===-1||!Array.isArray(P))return{origin:D,typeCounts:[],objectCount:o.snapshot.node_count};let U=P.length,B=Array(U),M=new Map,S=[],E=0,V=o.nodes,z=V.length;for(let j=0;j<z;j+=N){let O=V[j+p],W=V[j+I]??0;E+=W;let F;if(O>=0&&O<U){if(F=B[O],F===void 0)F={type:P[O],count:0,bytes:0},B[O]=F,S.push(F)}else{let L=`unknown(${O})`;if(F=M.get(L),F===void 0)F={type:L,count:0,bytes:0},M.set(L,F),S.push(F)}F.count++,F.bytes+=W}let A=S.sort((j,O)=>O.count-j.count),H=A.slice(0,20),_=A.slice(20),J=H.map(({type:j,count:O,bytes:W})=>({type:j,count:O,retainedBytes:W}));if(_.length>0){let j=0,O=0;for(let W of _)j+=W.count,O+=W.bytes;J.push({type:"other",count:j,retainedBytes:O})}return{origin:D,heapSizeBytes:E,objectCount:o.snapshot.node_count,typeCounts:J}}function Le(o,D,c){let C=["--heap-prof","--heap-prof-dir",D,"--heap-prof-name",c],p=o[0];if(p==="bun"||p?.endsWith("/bun"))return[p,...C,...o.slice(1)];return o}async function ge(o){let D=`${o.artifactDir}/${o.fileName}`,c=o.argv[0],C=c==="bun"||c?.endsWith("/bun"),p=Le(o.argv,o.artifactDir,o.fileName),I=C?o.env:{...process.env,...o.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${o.artifactDir} --heap-prof-name ${o.fileName}`},N=Bun.nanoseconds(),U=await Bun.spawn(p,{cwd:o.cwd,env:I,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,B=Bun.nanoseconds()-N,M=Bun.file(D);if(!await M.exists())return{diagnosticWallNs:B,exitCode:U,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${D} after exit ${U}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:D,argv:o.argv}}]};let S=await M.json(),E=fe(S,"heap-prof");return{diagnosticWallNs:B,exitCode:U,artifactPath:D,heap:E,warnings:[]}}import{Session as He}from"inspector/promises";var Je=1000;async function he(o,D={}){let c=D.intervalUs??Je,C=new He;C.connect();let p=Bun.nanoseconds();try{await C.post("Profiler.enable"),await C.post("Profiler.setSamplingInterval",{interval:c}),await C.post("Profiler.start");let I=await o(),{profile:N}=await C.post("Profiler.stop"),P=Bun.nanoseconds()-p,U=oe(N,"inspector",c);return{result:I,cpu:U,diagnosticWallNs:P}}finally{C.disconnect()}}import{profile as Ve}from"bun:jsc";var ze=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),be=4294967295;function ye(o,D){let c=D??o.interval*1e6,C=new Map,p=[];function I(F,L,K,G){let q=C.get(F);if(q===void 0)q=new Map,C.set(F,q);let Y=L??"",X=q.get(Y);if(X===void 0)X=p.length,q.set(Y,X),p.push({key:e("fr",F,Y),name:F,url:L,line:K,col:G});return X}function N(F){let L=F.line===be,K=L?void 0:F.line-1,G=L||F.column===be?void 0:F.column-1;return I(F.name,F.sourceURL,K,G)}let P=I("(root)",void 0,void 0,void 0),U=1,B={id:0,frameIx:P,children:new Map,selfUs:0,samples:0,totalUs:0},M=new Map([[0,B]]),S={llint:0,baseline:0,dfg:0,ftl:0},E=new Map,V=[],z=[];for(let F of o.traces){let L=F.frames,K=B;for(let Y=L.length-1;Y>=0;Y--){let X=N(L[Y]),ne=K.children.get(X);if(!ne)ne={id:U++,frameIx:X,children:new Map,selfUs:0,samples:0,totalUs:0},K.children.set(X,ne),M.set(ne.id,ne);K=ne}K.selfUs+=c,K.samples+=1,V.push(K.id),z.push(c);let G=L[0],q=G&&ze.get(G.category);if(q){S[q]++;let Y=E.get(q)??new Map;Y.set(K.frameIx,(Y.get(K.frameIx)??0)+1),E.set(q,Y)}}function A(F){let L=F.selfUs;for(let K of F.children.values())L+=A(K);return F.totalUs=L,L}A(B);let H=new Map;function _(F){let L=H.get(F.frameIx);if(L)L.selfUs+=F.selfUs,L.totalUs+=F.totalUs,L.samples+=F.samples;else H.set(F.frameIx,{frameIx:F.frameIx,selfUs:F.selfUs,totalUs:F.totalUs,samples:F.samples});for(let K of F.children.values())_(K)}_(B);let J=[...M.values()].map((F)=>({id:F.id,frameIx:F.frameIx,children:[...F.children.values()].map((L)=>L.id)})),j={origin:"jsc-profile",samplingIntervalUs:c,frames:p,nodes:J,totals:[...H.values()].sort((F,L)=>L.selfUs-F.selfUs),samples:{nodeIds:V,timeDeltasUs:z}},O=[...E.entries()].flatMap(([F,L])=>[...L.entries()].sort((K,G)=>G[1]-K[1]).slice(0,3).map(([K,G])=>({tier:F,frameKey:p[K].key,samples:G})));return{cpu:j,jit:{origin:"jsc-profile",tiers:S,topFramesByTier:O}}}var Ke=1000;async function we(o,D={}){let c=D.intervalUs??Ke,C,p=Bun.nanoseconds(),I=await Ve(async()=>(C=await o(),C),c),N=Bun.nanoseconds()-p,{cpu:P,jit:U}=ye(I.stackTraces,c);return{result:C,cpu:P,jit:U,diagnosticWallNs:N}}async function ue(o){let D=Bun.nanoseconds(),c=Bun.spawn(o.argv,{cwd:o.cwd,env:o.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),C=await c.exited,p=Bun.nanoseconds(),I=c.resourceUsage?.();return{wallNs:p-D,exitCode:C,userNs:I?Number(I.cpuTime.user)*1000:void 0,systemNs:I?Number(I.cpuTime.system)*1000:void 0,maxRssBytes:I?.maxRSS}}function xe(o){return o.trim().split(/\s+/).filter(Boolean)}var Ge=10,Ye=3000000000,qe=3;async function g(o){let D=o.warmup??qe;for(let M=0;M<D;M++)await ue(o);let c=[],C=o.runs??o.minRuns??Ge,p=o.runs!==void 0?0:o.minTotalNs??Ye,I=0,N=0;while(N<C||I<p){let M=await ue(o);if(c.push({i:N,wallNs:M.wallNs,exitCode:M.exitCode,userNs:M.userNs,systemNs:M.systemNs,maxRssBytes:M.maxRssBytes}),I+=M.wallNs,N++,o.runs!==void 0&&N>=o.runs)break}let P=c.map((M)=>M.wallNs),U=l(P),B=m(U,c.map((M)=>M.exitCode));return{trials:c,timing:U,warnings:B}}var Re=new URL("./runner.ts",import.meta.url).pathname,Qe="node_modules/.cache/ostia";function x(){return Math.max(1,navigator.hardwareConcurrency||1)}async function d(o){let c=`${o.outDir??Qe}/bench-tmp`,C=o.cwd??process.cwd(),p=Math.max(1,Math.floor(o.jobs??1)),I={timeBudgetMs:o.timeBudgetMs,minSamples:o.minSamples,gc:o.gc},N=o.suites.map((U)=>U.startsWith("/")?U:`${C}/${U}`),P=async(U,B)=>{let M=new Set,S=0,E,V=async()=>{while(E===void 0&&S<U.length){let z=S++;try{let A=Bun.spawn(U[z],{cwd:C,stdout:"inherit",stderr:"inherit",stdin:"ignore"});M.add(A);let H=await A.exited;if(M.delete(A),H!==0)throw Error(`Bench suite failed: ${B(z)} (runner exited ${H})`)}catch(A){E??=A instanceof Error?A:Error(String(A));for(let H of M)H.kill()}}};if(await Promise.all(Array.from({length:Math.min(p,U.length)},V)),E)throw E};try{let U=N.map((_)=>`${c}/${e("bench-plan",_)}.json`),B=N.map((_,J)=>["bun",Re,_,U[J],JSON.stringify({...I,filter:o.filter,isolate:o.isolate,planOnly:!0})]);await P(B,(_)=>o.suites[_]);let M=await Promise.all(U.map(async(_)=>{let{tasks:J}=await Bun.file(_).json();return J})),S=[];for(let _=0;_<M.length;_++){let J=M[_].filter((j)=>!j.isolate).map((j)=>j.id);if(J.length>0)S.push({suiteIndex:_,taskIds:J,markIsolated:!1});for(let j of M[_])if(j.isolate)S.push({suiteIndex:_,taskIds:[j.id],markIsolated:!0})}let E=S.map((_,J)=>`${c}/${e("bench-item",N[_.suiteIndex],J)}.json`),V=S.map((_,J)=>["bun",Re,N[_.suiteIndex],E[J],JSON.stringify({...I,taskIds:_.taskIds,..._.markIsolated&&{markIsolated:!0}})]);await P(V,(_)=>o.suites[S[_].suiteIndex]);let z=await Promise.all(E.map(t)),A=[],H=[];for(let _=0;_<M.length;_++){let J=S.findIndex((F)=>F.suiteIndex===_&&!F.markIsolated),j=J>=0?z[J]:void 0,O=0,W=new Map;S.forEach((F,L)=>{if(F.suiteIndex===_&&F.markIsolated)W.set(F.taskIds[0],z[L])});for(let F of M[_])if(F.isolate){let L=W.get(F.id);A.push(L.workloads[0]),H.push(L.runs[0])}else A.push(j.workloads[O]),H.push(j.runs[O]),O++}return r(A,H)}finally{await Bun.spawn(["rm","-rf",c]).exited}}var a={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function ie(o,D){if(o===0)return D===0?0:1/0;return(D-o)/o*100}function te(o,D,c){return o.runs.find((C)=>C.workloadId===D&&C.phase===c)}function f(o,D,c=a){let C=new Set(D.workloads.map((I)=>I.id)),p=[];for(let I of o.workloads){if(!C.has(I.id))continue;let N=w(o,D,I.id,c);if(N)p.push(N)}return p}function w(o,D,c,C=a){let p=te(o,c,"timing"),I=te(D,c,"timing"),N=te(o,c,"cpu"),P=te(D,c,"cpu"),U=te(o,c,"heap"),B=te(D,c,"heap"),M=p?.id??N?.id??U?.id,S=I?.id??P?.id??B?.id;if(!M||!S)return;let E=!1,V;if(p?.timing&&I?.timing){let H=ie(p.timing.median,I.timing.median),_=ie(p.timing.mean,I.timing.mean),J=H>C.timingPct?"regressed":H<-C.timingPct?"improved":"unchanged";if(J==="regressed")E=!0;V={medianDeltaPct:H,meanDeltaPct:_,verdict:J}}let z;if(N?.cpu&&P?.cpu){let H=new Map(N.cpu.totals.map((W)=>[N.cpu.frames[W.frameIx].key,W])),_=new Map(P.cpu.totals.map((W)=>[P.cpu.frames[W.frameIx].key,W])),J=new Map(N.cpu.frames.map((W)=>[W.key,W.name])),j=new Map(P.cpu.frames.map((W)=>[W.key,W.name]));z=[...new Set([...H.keys(),..._.keys()])].map((W)=>{let F=H.get(W)?.selfUs??0,L=_.get(W)?.selfUs??0;return{frameKey:W,name:j.get(W)??J.get(W)??W,baseSelfUs:F,candSelfUs:L,deltaPct:ie(F,L)}}).sort((W,F)=>Math.abs(F.deltaPct)-Math.abs(W.deltaPct));for(let W of z)if((W.baseSelfUs>=C.minFrameSelfUs||W.candSelfUs>=C.minFrameSelfUs)&&W.deltaPct>C.frameSelfPct)E=!0}let A;if(U?.heap&&B?.heap){let H=new Map(U.heap.typeCounts.map((j)=>[j.type,j])),_=new Map(B.heap.typeCounts.map((j)=>[j.type,j]));A=[...new Set([...H.keys(),..._.keys()])].map((j)=>{let O=H.get(j),W=_.get(j);return{type:j,baseCount:O?.count??0,candCount:W?.count??0,baseBytes:O?.retainedBytes,candBytes:W?.retainedBytes,deltaPct:ie(O?.count??0,W?.count??0)}}).sort((j,O)=>Math.abs(O.deltaPct)-Math.abs(j.deltaPct));for(let j of A)if(j.deltaPct>C.heapTypePct)E=!0}return{id:e("cmp",M,S),baselineRunId:M,candidateRunId:S,timing:V,frames:z,heapTypes:A,thresholds:C,verdict:E?"fail":"pass"}}function Z(o,D){if(D){let c=o.runs.find((C)=>C.id===D);return c?.cpu?[c]:[]}return o.runs.filter((c)=>c.phase==="cpu"&&c.cpu)}function re(o){let D=o.nodes,c=D.length,C=Xe(o),p=new Int32Array(c).fill(-1);for(let U=0;U<c;U++)for(let B of D[U].children){let M=C(B);if(M!==-1)p[M]=U}let I=[];for(let U=0;U<c;U++)if(p[U]===-1)I.push(U);let N=[],P=[];for(let U=I.length-1;U>=0;U--)P.push(I[U]);while(P.length>0){let U=P.pop();N.push(U);for(let B of D[U].children){let M=C(B);if(M!==-1&&p[M]===U)P.push(M)}}return{count:c,indexOf:C,parentIx:p,roots:I,order:N}}function Xe(o){let D=o.nodes,c=D.length,C=1/0,p=-1/0,I=!0;for(let P=0;P<c;P++){let U=D[P].id;if(!Number.isInteger(U)){I=!1;break}if(U<C)C=U;if(U>p)p=U}if(I&&c>0&&p-C<c*4+64){let P=p-C+1,U=new Int32Array(P).fill(-1);for(let B=0;B<c;B++)U[D[B].id-C]=B;return(B)=>{let M=B-C;return M>=0&&M<P?U[M]:-1}}let N=new Map;for(let P=0;P<c;P++)N.set(D[P].id,P);return(P)=>N.get(P)??-1}function Pe(o,D){let{count:c,indexOf:C,parentIx:p,order:I}=D,N=new Float64Array(c),P=new Float64Array(c),U=o.samples?.nodeIds??[],B=o.samples?.timeDeltasUs??[];for(let S=0;S<U.length;S++){let E=C(U[S]);if(E===-1)continue;N[E]+=B[S]??0,P[E]+=1}let M=new Float64Array(c);for(let S=I.length-1;S>=0;S--){let E=I[S];M[E]+=N[E];let V=p[E];if(V>=0)M[V]+=M[E]}return{selfUs:N,totalUs:M,samples:P}}var ke={name:"collapsed",async render(o,D={}){return{files:Z(o,D.runId).map((p)=>{let I=p.cpu,{nodes:N,frames:P}=I,U=re(I),B=Array(U.count);for(let z of U.order){let A=P[N[z].frameIx].name||"(anonymous)",H=U.parentIx[z];B[z]=H===-1?A:`${B[H]};${A}`}let M=new Float64Array(U.count),S=[],E=I.samples?.nodeIds??[];for(let z=0;z<E.length;z++){let A=U.indexOf(E[z]);if(A===-1)continue;if(M[A]++===0)S.push(A)}let V=Array(S.length);for(let z=0;z<S.length;z++){let A=S[z];V[z]=`${B[A]} ${M[A]}`}return{path:`${p.id}.collapsed.txt`,content:V.join(`
|
|
3
|
-
`)+(V.length>0?`
|
|
4
|
-
`:"")}})}}};var Te={name:"cpuprofile",async render(o,D={}){let c=Z(o,D.runId),C=[],p=[];for(let I of c){if(I.cpu?.origin!=="cpu-prof"&&I.cpu?.origin!=="inspector"){p.push(`${I.id} (origin ${I.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let N=I.artifacts.find((U)=>U.kind==="cpuprofile");if(!N){p.push(`${I.id} (no cpuprofile artifact recorded on this run)`);continue}let P=Bun.file(N.path);if(!await P.exists()){p.push(`${I.id} (artifact missing on disk: ${N.path})`);continue}C.push({path:`${I.id}.cpuprofile`,content:await P.text()})}if(C.length===0&&p.length>0)return{text:`No .cpuprofile artifacts available:
|
|
5
|
-
${p.map((I)=>` - ${I}`).join(`
|
|
6
|
-
`)}
|
|
7
|
-
`};return{files:C}}};var Ie={name:"json",async render(o){return{text:k(o)}}};var $e={name:"jsonl",async render(o){let{runs:D,...c}=o;return{text:`${[h(c),...D.map((p)=>h(p))].join(`
|
|
8
|
-
`)}
|
|
9
|
-
`}}};function ee(o){return(o/1e6).toFixed(3)}function ae(o){return o?.label??o?.command?.join(" ")??o?.entry?.task??o?.id??"unknown"}var ve=10,Ce=10,Ne={name:"markdown",async render(o){let D=new Map(o.workloads.map((p)=>[p.id,p])),c=[];c.push("# Profile Report",""),c.push(`Bun ${o.bunVersion} \xB7 ostia ${o.toolVersion} \xB7 ${o.platform.os}/${o.platform.arch} \xB7 ${o.createdAt}`,"");let C=o.runs.filter((p)=>p.phase==="timing"&&p.timing!==void 0);if(C.length>0){c.push("## Timing",""),c.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let I of C){let N=ae(D.get(I.workloadId)),P=I.timing;c.push(`| ${N} | ${ee(P.mean)} \xB1 ${ee(P.stddev)} | ${ee(P.min)}\u2026${ee(P.max)} | ${ee(P.median)} |`)}c.push("");let p=C.filter((I)=>I.warnings.length>0);if(p.length>0){c.push("### Warnings","");for(let I of p){let N=ae(D.get(I.workloadId));for(let P of I.warnings)c.push(`- **${N}**: ${P.message} (\`${P.code}\`)`)}c.push("")}}for(let p of o.runs){if(p.phase!=="cpu"&&p.phase!=="heap")continue;let I=ae(D.get(p.workloadId));if(p.phase==="cpu"){if(c.push(`## CPU capture - ${I}`,""),c.push(`instrumented, diagnostic wall ${ee(p.diagnosticWallNs??0)}ms`,""),p.cpu){c.push(`origin: \`${p.cpu.origin}\`, interval: ${p.cpu.samplingIntervalUs}\xB5s`,""),c.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let N=p.cpu.totals.reduce((P,U)=>P+U.selfUs,0)||1;for(let P of p.cpu.totals.slice(0,ve)){let U=p.cpu.frames[P.frameIx],B=(P.selfUs/N*100).toFixed(1);c.push(`| ${B}% | ${(P.selfUs/1000).toFixed(2)} | ${(P.totalUs/1000).toFixed(2)} | ${U?.name||"(anonymous)"} |`)}if(c.push(""),p.jit){let P=p.jit.tiers;c.push(`JIT tiers: LLInt ${P.llint} \xB7 Baseline ${P.baseline} \xB7 DFG ${P.dfg} \xB7 FTL ${P.ftl}`,"")}}}else if(c.push(`## Heap snapshot - ${I}`,""),c.push(`instrumented, diagnostic wall ${ee(p.diagnosticWallNs??0)}ms`,""),p.heap){c.push(`${p.heap.objectCount??"?"} objects, ${((p.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),c.push("| Count | Type |","|---|---|");for(let N of p.heap.typeCounts.slice(0,Ce))c.push(`| ${N.count} | ${N.type} |`);c.push("")}for(let N of p.artifacts)c.push(`- artifact: \`${N.path}\``);for(let N of p.warnings)c.push(`- ! ${N.message} (\`${N.code}\`)`);if(p.artifacts.length>0||p.warnings.length>0)c.push("")}if(o.comparisons&&o.comparisons.length>0){c.push("## Comparisons","");for(let p of o.comparisons){let I=o.runs.find((P)=>P.id===p.candidateRunId),N=ae(I?D.get(I.workloadId):void 0);if(c.push(`### ${p.verdict==="pass"?"\u2713":"\u2717"} ${N}`,""),p.timing){let P=p.timing.medianDeltaPct>0?"+":"";c.push(`- timing: ${P}${p.timing.medianDeltaPct.toFixed(1)}% median (**${p.timing.verdict}**)`)}for(let P of p.frames?.slice(0,ve)??[]){if(Math.abs(P.deltaPct)<0.5)continue;let U=P.deltaPct>0?"+":"";c.push(`- frame \`${P.name}\`: ${U}${P.deltaPct.toFixed(1)}% self-time (${(P.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(P.candSelfUs/1000).toFixed(2)}ms)`)}for(let P of p.heapTypes?.slice(0,Ce)??[]){if(Math.abs(P.deltaPct)<0.5)continue;let U=P.deltaPct>0?"+":"";c.push(`- heap \`${P.type}\`: ${U}${P.deltaPct.toFixed(1)}% count (${P.baseCount} \u2192 ${P.candCount})`)}c.push("")}}return{text:c.join(`
|
|
10
|
-
`)}}};var Ze=15;function le(o){return`n${o}`}function en(o,D,c){return`${(o||"(anonymous)").replace(/"/g,"'")} (self ${(D/1000).toFixed(2)}ms, total ${(c/1000).toFixed(2)}ms)`}function nn(o,D,c,C){let p=[];if(C<=0)return p;for(let I=0;I<D;I++){if(I===c)continue;let N=o[I];if(p.length===C&&N<=o[p[C-1]])continue;let P=p.length;while(P>0&&o[p[P-1]]<N)P--;if(p.splice(P,0,I),p.length>C)p.pop()}return p}var Ue={name:"mermaid",async render(o,D={}){let c=D.topN??Ze;return{files:Z(o,D.runId).map((I)=>{let N=I.cpu,{nodes:P,frames:U}=N,B=re(N),{selfUs:M,totalUs:S}=Pe(N,B),{parentIx:E}=B,V=B.roots[0]??-1,z=nn(M,B.count,V,c),A=new Set(V!==-1?[V]:[]),H=[];for(let J of z){H.length=0;for(let j=J;j!==-1;j=E[j])H.push(j);for(let j=H.length-1;j>=0;j--)A.add(H[j])}let _=["graph TD"];for(let J of A){let j=P[J].id;_.push(` ${le(j)}["${en(U[P[J].frameIx].name,M[J],S[J])}"]`)}for(let J of A){let j=E[J];if(j!==-1&&A.has(j))_.push(` ${le(P[j].id)} --> ${le(P[J].id)}`)}return{path:`${I.id}.mermaid.md`,content:`${_.join(`
|
|
11
|
-
`)}
|
|
12
|
-
`}})}}};function De(o){if(!o?.entry)return;if(o.entry.group!==void 0)return o.entry.group;let D=o.entry.task,c=D.lastIndexOf("/");return c===-1?void 0:D.slice(0,c)}function ce(o){let D=Math.min(...o.map((p)=>p.run.timing.median)),c=new Map;for(let p of o){let I=De(p.workload);if(I===void 0)continue;let N=c.get(I);if(N)N.push(p);else c.set(I,[p])}let C=new Map;for(let p of o){let I=De(p.workload);if(I===void 0){C.set(p,D);continue}let N=c.get(I)??[p],P=N.find((U)=>U.workload?.baseline);C.set(p,P?P.run.timing.median:Math.min(...N.map((U)=>U.run.timing.median)))}return C}function Q(o){return Number.isFinite(o)?Number(o.toPrecision(6)):o}function tn(o,D){return o?.entry?.task??o?.label??o?.command?.join(" ")??D.workloadId}function rn(o){let D=new Map(o.workloads.map((I)=>[I.id,I])),c=o.runs.filter((I)=>I.phase==="timing"&&I.timing!==void 0).map((I)=>({run:I,workload:D.get(I.workloadId)})),C=c.length>1?ce(c):void 0,p=new Map((o.comparisons??[]).map((I)=>[I.candidateRunId,I]));return c.map((I)=>{let{run:N,workload:P}=I,U=N.timing,B={task:tn(P,N),unit:"ns",samples:U.samples.length,mean:Q(U.mean),median:Q(U.median),stddev:Q(U.stddev),stddevPct:Q(U.mean===0?0:U.stddev/U.mean*100),min:Q(U.min),max:Q(U.max),warnings:N.warnings.map((S)=>S.data?{code:S.code,data:S.data}:{code:S.code})};if(P?.entry?.group!==void 0)B.group=P.entry.group;if(P?.description!==void 0)B.description=P.description;if(P?.groupDescription!==void 0)B.groupDescription=P.groupDescription;if(C)B.relative=Q(U.median/(C.get(I)??U.median));if(P?.baseline)B.baseline=!0;let M=p.get(N.id);if(M?.timing)B.delta={medianPct:Q(M.timing.medianDeltaPct),meanPct:Q(M.timing.meanDeltaPct),verdict:M.timing.verdict,pass:M.verdict==="pass"};return B})}var Fe={name:"minimal",async render(o){let D=rn(o).map((c)=>JSON.stringify(c));return{text:D.length>0?`${D.join(`
|
|
13
|
-
`)}
|
|
14
|
-
`:""}}};var sn="https://www.speedscope.app/file-format-schema.json";function Me(o){return o?.label??o?.command?.join(" ")??o?.entry?.task??"profile"}var Se={name:"speedscope",async render(o,D={}){let c=Z(o,D.runId),C=new Map(o.workloads.map((I)=>[I.id,I]));return{files:c.map((I)=>{let N=I.cpu,{nodes:P}=N,U=re(N),B=N.samples?.nodeIds??[],M=N.samples?.timeDeltasUs??[],S=Array(U.count);for(let A of U.order){let H=U.parentIx[A],_=P[A].frameIx;S[A]=H===-1?[_]:[...S[H],_]}let E=Array(B.length);for(let A=0;A<B.length;A++){let H=U.indexOf(B[A]);E[A]=H===-1?[]:S[H]}let V=0;for(let A=0;A<M.length;A++)V+=M[A];let z={$schema:sn,exporter:"ostia",name:Me(C.get(I.workloadId)),activeProfileIndex:0,shared:{frames:N.frames.map((A)=>({name:A.name||"(anonymous)",file:A.url,line:A.line!==void 0?A.line+1:void 0}))},profiles:[{type:"sampled",name:Me(C.get(I.workloadId)),unit:"microseconds",startValue:0,endValue:V,samples:E,weights:M}]};return{path:`${I.id}.speedscope.json`,content:`${JSON.stringify(z,null,2)}
|
|
15
|
-
`}})}}};function se(o){return(o/1e6).toFixed(3)}function pe(o){return o.label??o.command?.join(" ")??o.entry?.task??o.id}var Oe={name:"table",async render(o){let D=o.runs.filter((S)=>S.phase==="timing"&&S.timing!==void 0),c=new Map(o.workloads.map((S)=>[S.id,S]));if(D.length===0){let S=Be(o,c);return{text:S.length>0?`${S.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`:`(no timing runs)
|
|
18
|
-
`}}let C=D.map((S)=>{let E=c.get(S.workloadId);return{run:S,workload:E,label:E?pe(E):S.workloadId}}),p=C.length>1,I=ce(C),N=[],P=Math.max(7,...C.map((S)=>S.label.length)),U=p?`${"Command".padEnd(P)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(P)} Mean [ms] Min\u2026Max [ms]`;N.push(U),N.push("-".repeat(U.length));for(let S of C){let{run:E,label:V,workload:z}=S,A=E.timing,H=`${se(A.mean)} \xB1 ${se(A.stddev)}`,_=`${se(A.min)}\u2026${se(A.max)}`,J=`${V.padEnd(P)} ${H.padEnd(15)} ${_.padEnd(18)}`;if(p){let j=A.median/(I.get(S)??A.median);if(j===1)J+=z?.baseline?" 1.00\xD7 (baseline)":" 1.00\xD7";else if(j>1)J+=` ${j.toFixed(2)}\xD7 slower`;else J+=` ${(1/j).toFixed(2)}\xD7 faster`}N.push(J);for(let j of E.warnings)N.push(` ! ${j.message}`)}let B=an(o,c);if(B.length>0)N.push(""),N.push(...B);let M=Be(o,c);if(M.length>0)N.push(""),N.push(...M);return{text:`${N.join(`
|
|
19
|
-
`)}
|
|
20
|
-
`}}};function on(o,D,c){let C=o.runs.find((I)=>I.id===c),p=C?D.get(C.workloadId):void 0;return p?pe(p):c}function Be(o,D){if(!o.comparisons||o.comparisons.length===0)return[];let c=[];for(let C of o.comparisons){let p=on(o,D,C.candidateRunId),I=C.verdict==="pass"?"\u2713":"\u2717";if(c.push(`${I} ${p}`),C.timing){let N=C.timing.medianDeltaPct>0?"+":"";c.push(` timing: ${N}${C.timing.medianDeltaPct.toFixed(1)}% median (${C.timing.verdict})`)}if(C.frames)for(let N of C.frames.slice(0,We)){if(Math.abs(N.deltaPct)<0.5)continue;let P=N.deltaPct>0?"+":"";c.push(` frame ${N.name}: ${P}${N.deltaPct.toFixed(1)}% self-time (${(N.baseSelfUs/1000).toFixed(2)}ms -> ${(N.candSelfUs/1000).toFixed(2)}ms)`)}if(C.heapTypes)for(let N of C.heapTypes.slice(0,Ee)){if(Math.abs(N.deltaPct)<0.5)continue;let P=N.deltaPct>0?"+":"";c.push(` heap ${N.type}: ${P}${N.deltaPct.toFixed(1)}% count (${N.baseCount} -> ${N.candCount})`)}}return c}var We=5,Ee=5;function an(o,D){let c=[];for(let C of o.runs){if(C.phase!=="cpu"&&C.phase!=="heap")continue;let p=D.get(C.workloadId),I=p?pe(p):C.workloadId;if(C.phase==="cpu")if(C.cpu){c.push(`CPU capture - ${I} (instrumented, ${C.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${se(C.diagnosticWallNs??0)}ms)`);let N=C.cpu.totals.reduce((P,U)=>P+U.selfUs,0)||1;for(let P of C.cpu.totals.slice(0,We)){let U=C.cpu.frames[P.frameIx],B=(P.selfUs/N*100).toFixed(1);c.push(` ${B.padStart(5)}% ${(P.selfUs/1000).toFixed(2).padStart(8)}ms self ${U?.name??"?"}`)}}else c.push(`CPU capture - ${I} (instrumented, no evidence captured)`);else if(C.heap){let N=((C.heap.heapSizeBytes??0)/1e6).toFixed(2);c.push(`Heap snapshot - ${I} (instrumented, ${C.heap.objectCount??"?"} objects, ${N}MB)`);for(let P of C.heap.typeCounts.slice(0,Ee))c.push(` ${String(P.count).padStart(6)} ${P.type}`)}else c.push(`Heap snapshot - ${I} (instrumented, no evidence captured)`);for(let N of C.artifacts)c.push(` artifact: ${N.path}`);for(let N of C.warnings)c.push(` ! ${N.message}`)}return c}var n={table:Oe,json:Ie,markdown:Ne,jsonl:$e,minimal:Fe,collapsed:ke,mermaid:Ue,speedscope:Se,cpuprofile:Te};var cn="node_modules/.cache/ostia",me=1000;async function y(o){let D=s({runs:o.runs??null,warmup:o.warmup??null,cpu:o.cpu??!1,heap:o.heap??!1,cpuIntervalUs:o.cpuIntervalUs??me}),C=`${o.outDir??cn}/artifacts`,p=[],I=[];for(let N of o.commands){let P=Array.isArray(N)?N:xe(N),U=u(P,Array.isArray(N)?void 0:N);p.push(U);let B=await g({argv:P,cwd:o.cwd,env:o.env,runs:o.runs,warmup:o.warmup}),M=i({workload:U,configFingerprint:D,trials:B.trials,timing:B.timing,warnings:B.warnings});if(I.push(M),o.cpu){let S=`${M.id}-cpu.cpuprofile`,E=await de({argv:P,cwd:o.cwd,env:o.env,artifactDir:C,fileName:S,intervalUs:o.cpuIntervalUs??me});I.push(await Ae({workload:U,phase:"cpu",configFingerprint:D,diagnosticWallNs:E.diagnosticWallNs,exitCode:E.exitCode,cpu:E.cpu,artifactPath:E.artifactPath,artifactKind:"cpuprofile",warnings:E.warnings}))}if(o.heap){let S=`${M.id}-heap.heapsnapshot`,E=await ge({argv:P,cwd:o.cwd,env:o.env,artifactDir:C,fileName:S});I.push(await Ae({workload:U,phase:"heap",configFingerprint:D,diagnosticWallNs:E.diagnosticWallNs,exitCode:E.exitCode,heap:E.heap,artifactPath:E.artifactPath,artifactKind:"heapsnapshot",warnings:E.warnings}))}}return r(p,I)}async function Ae(o){let D=`${o.workload.id}-${o.phase}-${o.configFingerprint}`,c=o.artifactPath?[await T(D,o.artifactKind,o.artifactPath)]:[];return b({workload:o.workload,phase:o.phase,configFingerprint:o.configFingerprint,diagnosticWallNs:o.diagnosticWallNs,exitCode:o.exitCode,cpu:o.cpu,heap:o.heap,warnings:o.warnings,artifacts:c})}async function v(o,D={}){let c=R(o),C=s({intervalUs:D.intervalUs??me,origin:D.origin??"inspector"}),p=(B)=>B.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(D.origin==="jsc"){let{result:B,cpu:M,jit:S,diagnosticWallNs:E}=await we(o,D),V=b({workload:c,phase:"cpu",configFingerprint:C,diagnosticWallNs:E,cpu:M,jit:S,warnings:p(M),artifacts:[]});return{result:B,run:V}}let{result:I,cpu:N,diagnosticWallNs:P}=await he(o,D),U=b({workload:c,phase:"cpu",configFingerprint:C,diagnosticWallNs:P,cpu:N,warnings:p(N),artifacts:[]});return{result:I,run:U}}
|
|
21
|
-
export{x,d,a,f,w,g,n,y,v};
|
package/chunk-y1gkhb0y.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
function h(n){return JSON.stringify(O(n))}function O(n){if(Array.isArray(n))return n.map(O);if(n!==null&&typeof n==="object"){let a={};for(let d of Object.keys(n).sort())a[d]=O(n[d]);return a}return n}function e(n,...a){let d=Bun.CryptoHasher.hash("sha256",h(a),"hex");return`${n}_${d.slice(0,16)}`}var c="0.1.0";function r(n,a){return{schemaVersion:1,toolVersion:c,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:n,runs:a}}function u(n,a){return{id:e("wl","subprocess",n,process.cwd()),kind:"subprocess",command:n,label:a}}function R(n,a){return{id:e("wl","inprocess",n.name,n.toString()),kind:"inprocess",label:a}}function P(n,a,d={}){return{id:e("wl","inprocess-entry",n,a),kind:"inprocess",entry:{file:n,task:a,...d.group!==void 0&&{group:d.group}},...d.label!==void 0&&{label:d.label},...d.baseline!==void 0&&{baseline:d.baseline},...d.description!==void 0&&{description:d.description},...d.groupDescription!==void 0&&{groupDescription:d.groupDescription},...d.isolated!==void 0&&{isolated:d.isolated}}}function i(n){return{id:e("run",n.workload.id,"timing",n.configFingerprint,Bun.version,c),workloadId:n.workload.id,phase:"timing",instrumented:!1,configFingerprint:n.configFingerprint,trials:n.trials,timing:n.timing,warnings:n.warnings,artifacts:[],memory:Z(n.trials)}}function Z(n){let a=n.map((d)=>d.maxRssBytes).filter((d)=>d!==void 0);if(a.length===0)return;return{origin:"resourceUsage",perTrial:n.map((d)=>({rssBytes:d.maxRssBytes})),maxRssBytes:Math.max(...a)}}function b(n){return{id:e("run",n.workload.id,n.phase,n.configFingerprint,Bun.version,c),workloadId:n.workload.id,phase:n.phase,instrumented:!0,configFingerprint:n.configFingerprint,trials:[{i:0,wallNs:n.diagnosticWallNs,exitCode:n.exitCode}],diagnosticWallNs:n.diagnosticWallNs,cpu:n.cpu,heap:n.heap,jit:n.jit,warnings:n.warnings,artifacts:n.artifacts}}async function T(n,a,d){let f=await Bun.file(d).arrayBuffer(),w=new Bun.CryptoHasher("sha256");return w.update(f),{id:e("art",n,a,d),kind:a,path:d,sha256:w.digest("hex"),bytes:f.byteLength}}function s(n){return e("cfg",n)}function k(n){return`${JSON.stringify(O(n),null,2)}
|
|
3
|
-
`}async function o(n,a){await Bun.write(a,k(n))}async function t(n){let a=await Bun.file(n).text();return JSON.parse(a)}var H=[],v;function F(n,a,d){let g=v;v={name:n,description:d?.description,isolate:d?.isolate};try{a()}finally{v=g}}function S(n,a,d){H.push({groupName:v?.name,groupDescription:v?.description,groupIsolate:v?.isolate,name:n,fn:a,baseline:d?.baseline,opts:d})}function I(){return H}function C(){H.length=0,v=void 0}function p(n){return n.groupName?`${n.groupName}/${n.name}`:n.name}function N(n,a){return n.opts?.isolate??n.groupIsolate??a}function D(n,a){if(!a)return[...n];let d=new RegExp(a);return n.filter((g)=>d.test(p(g)))}function l(n){if(n.length===0)throw Error("computeTimingStats: samples must be non-empty");let a=n.length,d=z(n),g=0;for(let y=0;y<a;y++)g+=n[y];let f=g/a,w=B(d,0.5),x=0;for(let y=0;y<a;y++){let W=n[y]-f;x+=W*W}let A=Math.sqrt(x/a),J=d[0],E=d[a-1],q=B(d,0.25),_=B(d,0.75),M=_-q,V=q-1.5*M,G=_+1.5*M,K=q-3*M,U=_+3*M,j=0,L=0;for(let y=0;y<a;y++){let W=n[y];if(W<K||W>U)L++;else if(W<V||W>G)j++}return{unit:"ns",samples:n,mean:f,median:w,stddev:A,min:J,max:E,outliers:{mild:j,severe:L}}}function z(n){let a=new Float64Array(n.length);return a.set(n),a.sort(),a}function B(n,a){let d=n.length;if(d===1)return n[0];let g=a*(d-1),f=Math.floor(g),w=Math.ceil(g);if(f===w)return n[f];let x=g-f;return n[f]*(1-x)+n[w]*x}var Q=5000000,X=200;function m(n,a,d="subprocess"){let g=[],f=n.samples[0];if(f!==void 0){let x=z(n.samples),A=B(x,0.25),E=B(x,0.75)-A;if(f>n.median+3*E&&E>0)g.push({code:"slow-first-run",message:`First run took ${(f/1e6).toFixed(2)}ms, much slower than the median ${(n.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:f,medianNs:n.median}})}if(n.outliers.mild+n.outliers.severe>0)g.push({code:"outliers-detected",message:`${n.outliers.mild+n.outliers.severe} outlier(s) detected (${n.outliers.severe} severe, ${n.outliers.mild} mild).`,data:n.outliers});if(d==="subprocess"&&n.median<Q)g.push({code:"fast-command",message:`Median run time (${(n.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:n.median}});if(d==="inprocess"&&n.median<X)g.push({code:"below-timer-resolution",message:`Median run time (${n.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:n.median}});let w=a.filter((x)=>x!==void 0&&x!==0);if(w.length>0)g.push({code:"nonzero-exit",message:`${w.length} of ${a.length} trial(s) exited non-zero.`,data:{exitCodes:w}});return g}
|
|
4
|
-
export{h,e,c,r,u,R,P,i,b,T,s,k,o,t,l,m,F,S,I,C,p,N,D};
|