ostia 0.1.4 → 0.1.5
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 +9 -0
- package/chunk-gsjgejr1.js +21 -0
- package/chunk-y1gkhb0y.js +4 -0
- package/cli.js +29 -22
- package/index.d.ts +24 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/runner.ts +4 -4
- package/chunk-3rp84rbb.js +0 -4
- package/chunk-s1d2tx3w.js +0 -21
package/README.md
CHANGED
|
@@ -167,6 +167,15 @@ headroom, so numbers taken at `--jobs > 1` are noisier and not like-for-like wit
|
|
|
167
167
|
baseline measured at 1. It defaults to 1 for that reason; opt in for exploratory runs,
|
|
168
168
|
keep 1 for anything you `compare` or `ci` against.
|
|
169
169
|
|
|
170
|
+
`--isolate` gives every task its own child process instead of sharing its suite file's,
|
|
171
|
+
isolating each task's JIT tier state, inline caches and heap shape from every other task
|
|
172
|
+
in the run - the same guarantee suite files already get from each other, at task
|
|
173
|
+
granularity. `task(name, fn, { isolate })` / `group(name, fn, { isolate })` override the
|
|
174
|
+
suite-wide default for mixed suites (e.g. a couple of outlier-prone tasks isolated, the
|
|
175
|
+
rest sharing a process). `--jobs` then pools across those per-task processes the same way
|
|
176
|
+
it pools across per-file ones, so pair a higher `--jobs` with `--isolate` deliberately -
|
|
177
|
+
overhead now scales with task count, not file count.
|
|
178
|
+
|
|
170
179
|
```
|
|
171
180
|
Command Mean [ms] Min…Max [ms] Relative
|
|
172
181
|
--------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,21 @@
|
|
|
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};
|
|
@@ -0,0 +1,4 @@
|
|
|
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};
|
package/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
import{
|
|
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-gsjgejr1.js";import{e,c,r,u,i,s,o,t}from"./chunk-y1gkhb0y.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 j of P.scan({cwd:l,absolute:!1}))m.add(j)}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 W(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 V(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 z(p,l){return`${p.baselineDir}/${l??p.baseline}.json`}class T 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=z(l,p.baselineName);if(!await Bun.file(m).exists())throw new T(m);let h=await t(m),b=[],P=0,j=0,D=0;for(let C of l.workloads){let A=u(C.command,C.label),v=await _(C.inputs??[]),U=s({runs:l.runs,warmup:l.warmup}),H=q({workloadId:A.id,phase:"timing",configFingerprint:U,bunVersion:Bun.version,toolVersion:c,instrumented:!1,inputsDigest:v}),J=p.full?void 0:await M(l.outDir,H),S,B;if(J)S=J,B="cached",j++;else{P++;let O=await g({argv:C.command,runs:l.runs??void 0,warmup:l.warmup});S=i({workload:A,configFingerprint:U,trials:O.trials,timing:O.timing,warnings:O.warnings}),await W(l.outDir,H,S),B="executed",D++}b.push({workload:A,status:B,run:S})}let R=r(b.map((C)=>C.workload),b.map((C)=>C.run)),N=0,E=0,F=0;for(let C of b){let A=w(h,R,C.workload.id,l.thresholds);if(!A){F++;continue}if(C.comparison=A,A.verdict==="pass")N++;else E++}return R.comparisons=b.map((C)=>C.comparison).filter((C)=>C!==void 0),{document:R,summary:{total:l.workloads.length,affected:P,cached:j,executed:D,passed:N,regressed:E,missingBaseline:F,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 I(
|
|
7
|
-
`)}else if(
|
|
8
|
-
${
|
|
6
|
+
`}async function I(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
|
+
`)}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
|
+
${m.content}
|
|
9
9
|
`)}var ee=`ostia run [flags] <command...>
|
|
10
10
|
|
|
11
11
|
Run one or more commands N times with warmup and report timing statistics.
|
|
@@ -52,6 +52,13 @@ Flags:
|
|
|
52
52
|
--gc Bun.gc(true) between trials (default: off - hides allocation cost)
|
|
53
53
|
--filter REGEX only run tasks whose "group/name" id matches this regex (substring,
|
|
54
54
|
case-sensitive; unmatched tasks are skipped, not timed)
|
|
55
|
+
--isolate give every task its own subprocess instead of sharing its suite
|
|
56
|
+
file's, isolating JIT tier state and heap shape between tasks the
|
|
57
|
+
way suite files are already isolated from each other. Per-task
|
|
58
|
+
{ isolate } / per-group { isolate } override this default.
|
|
59
|
+
--jobs then pools across those per-task processes, so pair a
|
|
60
|
+
higher --jobs with --isolate deliberately: overhead now scales
|
|
61
|
+
with task count, not file count.
|
|
55
62
|
--out-dir PATH directory for scratch IPC files (default: node_modules/.cache/ostia)
|
|
56
63
|
--export-json PATH write the full ProfileDocument to PATH
|
|
57
64
|
--format FORMAT table | json | jsonl | markdown | minimal (default: table)
|
|
@@ -77,7 +84,7 @@ Examples:
|
|
|
77
84
|
ostia bench --time-budget 1000 --min-samples 50 benches/*.ts
|
|
78
85
|
ostia bench benches/*.ts --filter parse
|
|
79
86
|
ostia bench benches/*.ts --jobs auto --format minimal
|
|
80
|
-
`,
|
|
87
|
+
`,Z=`ostia compare <base.json> <candidate.json>
|
|
81
88
|
ostia compare <candidate.json> --baseline <path.json>
|
|
82
89
|
|
|
83
90
|
Compare two ProfileDocuments (matched by workload id) and rank timing/frame/heap deltas.
|
|
@@ -129,22 +136,22 @@ Flags:
|
|
|
129
136
|
--help show this message
|
|
130
137
|
|
|
131
138
|
Exit codes: 0 pass, 1 regression, 2 harness error (missing config/baseline, spawn failure).
|
|
132
|
-
`;function oe(
|
|
133
|
-
`),2;let
|
|
134
|
-
`),2}if(l.exportJson)await o(
|
|
139
|
+
`;function oe(p){let l=[],m,k,h=!1,b=!1,P,j,D,R="table",N=!1,E=!1;for(let F=0;F<p.length;F++){let C=p[F];switch(C){case"--runs":m=Number(p[++F]);break;case"--warmup":k=Number(p[++F]);break;case"--cpu":h=!0;break;case"--heap":b=!0;break;case"--cpu-interval":P=Number(p[++F]);break;case"--out-dir":j=p[++F];break;case"--export-json":D=p[++F];break;case"--format":R=p[++F];break;case"--quiet":N=!0;break;case"--help":case"-h":E=!0;break;default:l.push(C)}}return{commands:l,runs:m,warmup:k,cpu:h,heap:b,cpuIntervalUs:P,outDir:j,exportJson:D,format:R,quiet:N,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
|
+
`),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 I(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,j=!1,D,R,N="table",E=!1,F=!1;for(let C=0;C<p.length;C++){let A=p[C];switch(A){case"--time-budget":m=Number(p[++C]);break;case"--min-samples":k=Number(p[++C]);break;case"--jobs":{let v=p[++C];h=v==="auto"?x():Number(v);break}case"--gc":b=!0;break;case"--filter":P=p[++C];break;case"--isolate":j=!0;break;case"--out-dir":D=p[++C];break;case"--export-json":R=p[++C];break;case"--format":N=p[++C];break;case"--quiet":E=!0;break;case"--help":case"-h":F=!0;break;default:l.push(A)}}return{suites:l,timeBudgetMs:m,minSamples:k,jobs:h,gc:b,filter:P,isolate:j,outDir:D,exportJson:R,format:N,quiet:E,help:F}}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(", ")}
|
|
135
142
|
`),2;if(l.jobs!==void 0&&!(l.jobs>=1))return process.stderr.write(`--jobs expects a positive integer or "auto".
|
|
136
|
-
`),2;let
|
|
137
|
-
`),2}if(l.exportJson)await o(
|
|
138
|
-
`),2}let
|
|
139
|
-
`),2}let
|
|
140
|
-
`),2;let
|
|
141
|
-
`),2}let
|
|
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 I(h)}return 0}function le(p){let l=[],m,k,h="table",b=!1,P=!1;for(let j=0;j<p.length;j++){let D=p[j];switch(D){case"--baseline":m=p[++j];break;case"--export-json":k=p[++j];break;case"--format":h=p[++j];break;case"--quiet":b=!0;break;case"--help":case"-h":P=!0;break;default:l.push(D)}}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(R){return process.stderr.write(`Failed to load documents: ${R instanceof Error?R.message:String(R)}
|
|
145
|
+
`),2}let P=f(h,b),j={...b,comparisons:P};if(l.exportJson)await o(j,l.exportJson);if(!l.quiet){let N=await n[l.format].render(j,{});await I(N)}return P.some((R)=>R.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)}
|
|
146
|
+
`),2}let h=await n[l.format].render(m,{});return await I(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 j=p[P];switch(j){case"--format":{let D=p[++P]??"";m=me[D]??D;break}case"--run":k=p[++P];break;case"--out-dir":h=p[++P];break;case"--help":case"-h":b=!0;break;default:l=j}}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
|
+
`),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
|
+
`),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}".
|
|
142
149
|
`:`No CPU evidence found in this document (no cpu-phase runs). Capture some with "ostia run --cpu ...".
|
|
143
|
-
`),2;return await I(
|
|
144
|
-
`),2;if(
|
|
145
|
-
`),2;let
|
|
146
|
-
`),2;return process.stderr.write(`CI run failed: ${
|
|
147
|
-
`),2}if(l.exportJson)await o(
|
|
150
|
+
`),2;return await I(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 V();if(!m)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
|
|
151
|
+
`),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 T)return process.stderr.write(`${h.message}
|
|
153
|
+
`),2;return process.stderr.write(`CI run failed: ${h instanceof Error?h.message:String(h)}
|
|
154
|
+
`),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
|
|
148
155
|
|
|
149
156
|
Commands:
|
|
150
157
|
run Run commands N times and report timing/CPU/heap
|
|
@@ -155,5 +162,5 @@ Commands:
|
|
|
155
162
|
viz Render CPU evidence as collapsed/mermaid/speedscope/cpuprofile
|
|
156
163
|
|
|
157
164
|
Run "ostia <command> --help" for details.
|
|
158
|
-
`),
|
|
159
|
-
`),2}}if(import.meta.main)we().then((
|
|
165
|
+
`),p===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${p}". Run "ostia --help".
|
|
166
|
+
`),2}}if(import.meta.main)we().then((p)=>process.exit(p));
|
package/index.d.ts
CHANGED
|
@@ -63,6 +63,10 @@ export interface Workload {
|
|
|
63
63
|
/** The enclosing group's `group(name, fn, { description })`. Repeated on every
|
|
64
64
|
* workload in the group so each record is self-contained. */
|
|
65
65
|
groupDescription?: string;
|
|
66
|
+
/** Whether this task ran in a subprocess dedicated to it alone (`isolate`
|
|
67
|
+
* on the task, its group, or the suite), vs. sharing its suite file's
|
|
68
|
+
* subprocess with other tasks. */
|
|
69
|
+
isolated?: boolean;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
type Phase = "timing" | "cpu" | "heap" | "memstats";
|
|
@@ -238,10 +242,21 @@ interface BenchOptions {
|
|
|
238
242
|
* 1). Files are independent by design, so this is a wall-clock win for
|
|
239
243
|
* multi-file suites, but concurrent CPU-bound processes contend for cores,
|
|
240
244
|
* caches, memory bandwidth and turbo headroom: timings taken under `jobs > 1`
|
|
241
|
-
* are noisier and not like-for-like with a baseline measured at 1.
|
|
245
|
+
* are noisier and not like-for-like with a baseline measured at 1. When
|
|
246
|
+
* `isolate` puts some tasks in their own subprocess, `jobs` pools across
|
|
247
|
+
* those per-task processes the same way - so the same noise/wall-clock
|
|
248
|
+
* tradeoff now scales with task count, not just file count. */
|
|
242
249
|
jobs?: number;
|
|
243
250
|
outDir?: string;
|
|
244
251
|
cwd?: string;
|
|
252
|
+
/** Give every task its own subprocess instead of sharing its suite file's,
|
|
253
|
+
* isolating each task's JIT tier state, inline caches and heap shape from
|
|
254
|
+
* every other task the way suite files are already isolated from each
|
|
255
|
+
* other. `TaskOptions.isolate` / `GroupOptions.isolate` override this per
|
|
256
|
+
* task or group for mixed suites (e.g. a few outlier-prone tasks isolated,
|
|
257
|
+
* many cheap ones sharing a process). Multiplies process-spawn overhead by
|
|
258
|
+
* task count instead of file count. */
|
|
259
|
+
isolate?: boolean;
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
export declare function bench(opts: BenchOptions): Promise<ProfileDocument>;
|
|
@@ -258,12 +273,20 @@ export interface TaskOptions {
|
|
|
258
273
|
/** What this task measures and why. Flows into `Workload.description` so the
|
|
259
274
|
* intent travels with the numbers instead of living only in a source comment. */
|
|
260
275
|
description?: string;
|
|
276
|
+
/** Give this task its own subprocess instead of sharing its suite file's,
|
|
277
|
+
* isolating its JIT tier state and heap shape from every other task in the
|
|
278
|
+
* run. Overrides the group's and the suite-wide `bench({ isolate })` /
|
|
279
|
+
* `--isolate` default for this task only. */
|
|
280
|
+
isolate?: boolean;
|
|
261
281
|
}
|
|
262
282
|
|
|
263
283
|
export interface GroupOptions {
|
|
264
284
|
/** What this group measures and why. Flows into `Workload.groupDescription`
|
|
265
285
|
* on every task in the group. */
|
|
266
286
|
description?: string;
|
|
287
|
+
/** Default `isolate` for every task in this group, unless a task overrides
|
|
288
|
+
* it with its own `TaskOptions.isolate`. */
|
|
289
|
+
isolate?: boolean;
|
|
267
290
|
}
|
|
268
291
|
|
|
269
292
|
export declare function group(name: string, fn: () => void, opts?: GroupOptions): void;
|
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{d,f,n,y,v}from"./chunk-gsjgejr1.js";import{o,t,F,S}from"./chunk-y1gkhb0y.js";export{d as bench,f as compareDocuments,F as group,t as loadDocument,v as profile,n as renderers,y as run,o as saveDocument,S 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,m,C,N,
|
|
4
|
-
`),2;let
|
|
5
|
-
`),2;let f=D(T,
|
|
6
|
-
`),2;let
|
|
3
|
+
import{r,P,i,s,o,l,m,I,C,p,N,D}from"./chunk-y1gkhb0y.js";var z=500,H=20,A=3,j=10,v=2,X=0.1,q=1000,K=1e4;function J(n){let e=Math.log10(Math.max(1,n)/1e6),a=Math.round(A+v*e);return Math.min(j,Math.max(A,a))}function Q(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(q/n),Math.ceil(e/(n*K)))}async function U(n,e={}){let a=(e.timeBudgetMs??z)*1e6,d=a*(e.warmupFraction??X),T=Bun.nanoseconds(),f=0,b=0;while(b<d){let g=n();O(B(g)?await g:g),f++,b=Bun.nanoseconds()-T}let h;if(f>0)h=Math.max(1,b/f);else{let g=Bun.nanoseconds(),w=n();O(B(w)?await w:w),h=Math.max(1,Bun.nanoseconds()-g)}let t=G(h,a);if(t>1){let g=Bun.nanoseconds();for(let w=0;w<t;w++){let k=n();O(B(k)?await k:k)}h=Math.max(1,(Bun.nanoseconds()-g)/t),t=G(h,a)}let u=h*t,S=e.minSamples??Q(u,a),c=[],M=Bun.nanoseconds(),F=0,R=0;while(R<S||F<a){let g=Bun.nanoseconds();for(let k=0;k<t;k++){let _=n();O(B(_)?await _:_)}let w=Bun.nanoseconds();if(c.push({i:R,wallNs:(w-g)/t}),R++,F=Bun.nanoseconds()-M,e.gc)Bun.gc(!0)}let W=c.map((g)=>g.wallNs),y=l(W),E=m(y,[],"inprocess"),x=J(u);if(c.length<x)E.push({code:"low-sample-count",message:`Only ${c.length} sample(s) at ~${V(u)} per trial; ${x} is the floor for this cost class. Raise minSamples or the time budget for a steadier number.`,data:{samples:c.length,target:x,trialCostNs:u}});return{trials:c,timing:y,warnings:E}}function V(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 Y(){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 d=a?JSON.parse(a):{};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=D(T,d.filter);if(d.taskIds){let t=new Set(d.taskIds);f=f.filter((u)=>t.has(p(u)))}if(f.length===0)return process.stderr.write(`bench runner: --filter ${JSON.stringify(d.filter)} matched zero of ${T.length} registered tasks in ${n}.
|
|
6
|
+
`),2;if(d.planOnly){let t=f.map((u)=>({id:p(u),isolate:N(u,d.isolate??!1)}));return await Bun.write(e,JSON.stringify({tasks:t})),0}let b=[],h=[];for(let t of f){let u=p(t),S=P(n,u,{label:u,baseline:t.baseline,group:t.groupName,description:t.opts?.description,groupDescription:t.groupDescription,isolated:d.markIsolated});b.push(S);let c={...d,...t.opts?.timeBudgetMs!==void 0&&{timeBudgetMs:t.opts.timeBudgetMs},...t.opts?.minSamples!==void 0&&{minSamples:t.opts.minSamples}},M=await U(t.fn,c);h.push(i({workload:S,configFingerprint:s({timeBudgetMs:c.timeBudgetMs??null,minSamples:c.minSamples??null,gc:c.gc??!1}),trials:M.trials,timing:M.timing,warnings:M.warnings}))}return await o(r(b,h),e),0}Y().then((n)=>process.exit(n));
|
package/chunk-3rp84rbb.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
function g(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",g(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}}}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:U(n.trials)}}function U(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 h(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 p=await Bun.file(d).arrayBuffer(),k=new Bun.CryptoHasher("sha256");return k.update(p),{id:e("art",n,a,d),kind:a,path:d,sha256:k.digest("hex"),bytes:p.byteLength}}function s(n){return e("cfg",n)}function y(n){return`${JSON.stringify(O(n),null,2)}
|
|
3
|
-
`}async function o(n,a){await Bun.write(a,y(n))}async function t(n){let a=await Bun.file(n).text();return JSON.parse(a)}var _=[],S;function F(n,a,d){let f=S;S={name:n,description:d?.description};try{a()}finally{S=f}}function v(n,a,d){_.push({groupName:S?.name,groupDescription:S?.description,name:n,fn:a,baseline:d?.baseline,opts:d})}function C(){return _}function N(){_.length=0,S=void 0}function x(n){return n.groupName?`${n.groupName}/${n.name}`:n.name}function D(n,a){if(!a)return[...n];let d=new RegExp(a);return n.filter((f)=>d.test(x(f)))}function l(n){if(n.length===0)throw Error("computeTimingStats: samples must be non-empty");let a=n.length,d=L(n),f=0;for(let b=0;b<a;b++)f+=n[b];let p=f/a,k=B(d,0.5),w=0;for(let b=0;b<a;b++){let W=n[b]-p;w+=W*W}let M=Math.sqrt(w/a),H=d[0],E=d[a-1],A=B(d,0.25),q=B(d,0.75),I=q-A,z=A-1.5*I,V=q+1.5*I,G=A-3*I,K=q+3*I,J=0,j=0;for(let b=0;b<a;b++){let W=n[b];if(W<G||W>K)j++;else if(W<z||W>V)J++}return{unit:"ns",samples:n,mean:p,median:k,stddev:M,min:H,max:E,outliers:{mild:J,severe:j}}}function L(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 f=a*(d-1),p=Math.floor(f),k=Math.ceil(f);if(p===k)return n[p];let w=f-p;return n[p]*(1-w)+n[k]*w}var Z=5000000,Q=200;function m(n,a,d="subprocess"){let f=[],p=n.samples[0];if(p!==void 0){let w=L(n.samples),M=B(w,0.25),E=B(w,0.75)-M;if(p>n.median+3*E&&E>0)f.push({code:"slow-first-run",message:`First run took ${(p/1e6).toFixed(2)}ms, much slower than the median ${(n.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:p,medianNs:n.median}})}if(n.outliers.mild+n.outliers.severe>0)f.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<Z)f.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<Q)f.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 k=a.filter((w)=>w!==void 0&&w!==0);if(k.length>0)f.push({code:"nonzero-exit",message:`${k.length} of ${a.length} trial(s) exited non-zero.`,data:{exitCodes:k}});return f}
|
|
4
|
-
export{g,e,c,r,u,R,P,i,h,T,s,y,o,t,l,m,F,v,C,N,x,D};
|
package/chunk-s1d2tx3w.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{g,e,r,u,R,i,h,T,s,y,t,l,m}from"./chunk-3rp84rbb.js";function Ae(o){return o.startsWith("file://")?o.slice(7):o}function oe(o,D,c){let C=o.nodes,x=C.length,v=new Map,N=[],P=new Map,U=new Int32Array(x);for(let W=0;W<x;W++){let O=C[W],S=O.callFrame,_=Ae(S.url),K=v.get(S.functionName);if(K===void 0)K=new Map,v.set(S.functionName,K);let G=K.get(_);if(G===void 0)G=N.length,K.set(_,G),N.push({key:e("fr",S.functionName,_),name:S.functionName,url:_||void 0,line:S.lineNumber>=0?S.lineNumber:void 0,col:S.columnNumber>=0?S.columnNumber:void 0});U[W]=G,P.set(O.id,W)}let M=Array(x);for(let W=0;W<x;W++){let O=C[W];M[W]={id:O.id,frameIx:U[P.get(O.id)],children:O.children??[]}}let F=new Float64Array(x),B=new Float64Array(x),{samples:A,timeDeltas:J}=o;for(let W=0;W<A.length;W++){let O=P.get(A[W]);if(O===void 0)continue;F[O]+=J[W]??0,B[O]+=1}let H=new Int32Array(x).fill(-1);for(let W=0;W<x;W++){let O=C[W].children;if(!O)continue;for(let S of O){let _=P.get(S);if(_!==void 0)H[_]=W}}let E=[],L=[];for(let W=x-1;W>=0;W--)if(H[W]===-1)L.push(W);while(L.length>0){let W=L.pop();E.push(W);let O=C[W].children;if(!O)continue;for(let S of O){let _=P.get(S);if(_!==void 0&&H[_]===W)L.push(_)}}let V=new Float64Array(x);for(let W=E.length-1;W>=0;W--){let O=E[W];V[O]+=F[O];let S=H[O];if(S>=0)V[S]+=V[O]}let z=Array(N.length),j=[];for(let W=0;W<x;W++){let O=M[W].frameIx,S=z[O];if(S)S.selfUs+=F[W],S.totalUs+=V[W],S.samples+=B[W];else{let _={frameIx:O,selfUs:F[W],totalUs:V[W],samples:B[W]};z[O]=_,j.push(_)}}return{origin:D,samplingIntervalUs:c,frames:N,nodes:M,totals:j.sort((W,O)=>O.selfUs-W.selfUs),samples:{nodeIds:o.samples,timeDeltasUs:o.timeDeltas}}}function je(o,D,c,C){let x=["--cpu-prof","--cpu-prof-dir",D,"--cpu-prof-name",c,"--cpu-prof-interval",String(C)],v=o[0];if(v==="bun"||v?.endsWith("/bun"))return[v,...x,...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"),x=je(o.argv,o.artifactDir,o.fileName,o.intervalUs),v=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(x,{cwd:o.cwd,env:v,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,M=Bun.nanoseconds()-N,F=Bun.file(D);if(!await F.exists())return{diagnosticWallNs:M,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 B=await F.json(),A=oe(B,"cpu-prof",o.intervalUs),J=B.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:M,exitCode:U,artifactPath:D,cpu:A,warnings:J}}function fe(o,D="heap-prof"){let{node_fields:c,node_types:C}=o.snapshot.meta,x=c.indexOf("type"),v=c.indexOf("self_size"),N=c.length,P=C[0];if(x===-1||v===-1||!Array.isArray(P))return{origin:D,typeCounts:[],objectCount:o.snapshot.node_count};let U=P.length,M=Array(U),F=new Map,B=[],A=0,J=o.nodes,H=J.length;for(let j=0;j<H;j+=N){let W=J[j+x],O=J[j+v]??0;A+=O;let S;if(W>=0&&W<U){if(S=M[W],S===void 0)S={type:P[W],count:0,bytes:0},M[W]=S,B.push(S)}else{let _=`unknown(${W})`;if(S=F.get(_),S===void 0)S={type:_,count:0,bytes:0},F.set(_,S),B.push(S)}S.count++,S.bytes+=O}let E=B.sort((j,W)=>W.count-j.count),L=E.slice(0,20),V=E.slice(20),z=L.map(({type:j,count:W,bytes:O})=>({type:j,count:W,retainedBytes:O}));if(V.length>0){let j=0,W=0;for(let O of V)j+=O.count,W+=O.bytes;z.push({type:"other",count:j,retainedBytes:W})}return{origin:D,heapSizeBytes:A,objectCount:o.snapshot.node_count,typeCounts:z}}function _e(o,D,c){let C=["--heap-prof","--heap-prof-dir",D,"--heap-prof-name",c],x=o[0];if(x==="bun"||x?.endsWith("/bun"))return[x,...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"),x=_e(o.argv,o.artifactDir,o.fileName),v=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(x,{cwd:o.cwd,env:v,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,M=Bun.nanoseconds()-N,F=Bun.file(D);if(!await F.exists())return{diagnosticWallNs:M,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 B=await F.json(),A=fe(B,"heap-prof");return{diagnosticWallNs:M,exitCode:U,artifactPath:D,heap:A,warnings:[]}}import{Session as Le}from"inspector/promises";var He=1000;async function he(o,D={}){let c=D.intervalUs??He,C=new Le;C.connect();let x=Bun.nanoseconds();try{await C.post("Profiler.enable"),await C.post("Profiler.setSamplingInterval",{interval:c}),await C.post("Profiler.start");let v=await o(),{profile:N}=await C.post("Profiler.stop"),P=Bun.nanoseconds()-x,U=oe(N,"inspector",c);return{result:v,cpu:U,diagnosticWallNs:P}}finally{C.disconnect()}}import{profile as ze}from"bun:jsc";var Je=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,x=[];function v(S,_,K,G){let q=C.get(S);if(q===void 0)q=new Map,C.set(S,q);let Y=_??"",X=q.get(Y);if(X===void 0)X=x.length,q.set(Y,X),x.push({key:e("fr",S,Y),name:S,url:_,line:K,col:G});return X}function N(S){let _=S.line===be,K=_?void 0:S.line-1,G=_||S.column===be?void 0:S.column-1;return v(S.name,S.sourceURL,K,G)}let P=v("(root)",void 0,void 0,void 0),U=1,M={id:0,frameIx:P,children:new Map,selfUs:0,samples:0,totalUs:0},F=new Map([[0,M]]),B={llint:0,baseline:0,dfg:0,ftl:0},A=new Map,J=[],H=[];for(let S of o.traces){let _=S.frames,K=M;for(let Y=_.length-1;Y>=0;Y--){let X=N(_[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),F.set(ne.id,ne);K=ne}K.selfUs+=c,K.samples+=1,J.push(K.id),H.push(c);let G=_[0],q=G&&Je.get(G.category);if(q){B[q]++;let Y=A.get(q)??new Map;Y.set(K.frameIx,(Y.get(K.frameIx)??0)+1),A.set(q,Y)}}function E(S){let _=S.selfUs;for(let K of S.children.values())_+=E(K);return S.totalUs=_,_}E(M);let L=new Map;function V(S){let _=L.get(S.frameIx);if(_)_.selfUs+=S.selfUs,_.totalUs+=S.totalUs,_.samples+=S.samples;else L.set(S.frameIx,{frameIx:S.frameIx,selfUs:S.selfUs,totalUs:S.totalUs,samples:S.samples});for(let K of S.children.values())V(K)}V(M);let z=[...F.values()].map((S)=>({id:S.id,frameIx:S.frameIx,children:[...S.children.values()].map((_)=>_.id)})),j={origin:"jsc-profile",samplingIntervalUs:c,frames:x,nodes:z,totals:[...L.values()].sort((S,_)=>_.selfUs-S.selfUs),samples:{nodeIds:J,timeDeltasUs:H}},W=[...A.entries()].flatMap(([S,_])=>[..._.entries()].sort((K,G)=>G[1]-K[1]).slice(0,3).map(([K,G])=>({tier:S,frameKey:x[K].key,samples:G})));return{cpu:j,jit:{origin:"jsc-profile",tiers:B,topFramesByTier:W}}}var Ve=1000;async function we(o,D={}){let c=D.intervalUs??Ve,C,x=Bun.nanoseconds(),v=await ze(async()=>(C=await o(),C),c),N=Bun.nanoseconds()-x,{cpu:P,jit:U}=ye(v.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,x=Bun.nanoseconds(),v=c.resourceUsage?.();return{wallNs:x-D,exitCode:C,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 Ke=10,Ge=3000000000,Ye=3;async function f(o){let D=o.warmup??Ye;for(let F=0;F<D;F++)await ue(o);let c=[],C=o.runs??o.minRuns??Ke,x=o.runs!==void 0?0:o.minTotalNs??Ge,v=0,N=0;while(N<C||v<x){let F=await ue(o);if(c.push({i:N,wallNs:F.wallNs,exitCode:F.exitCode,userNs:F.userNs,systemNs:F.systemNs,maxRssBytes:F.maxRssBytes}),v+=F.wallNs,N++,o.runs!==void 0&&N>=o.runs)break}let P=c.map((F)=>F.wallNs),U=l(P),M=m(U,c.map((F)=>F.exitCode));return{trials:c,timing:U,warnings:M}}var qe=new URL("./runner.ts",import.meta.url).pathname,Qe="node_modules/.cache/ostia";function k(){return Math.max(1,navigator.hardwareConcurrency||1)}async function p(o){let c=`${o.outDir??Qe}/bench-tmp`,C=o.cwd??process.cwd(),x=Math.max(1,Math.floor(o.jobs??1)),v={timeBudgetMs:o.timeBudgetMs,minSamples:o.minSamples,gc:o.gc,filter:o.filter},N=Array(o.suites.length),P=new Set,U=0,M,F=async(H)=>{let E=o.suites[H],L=E.startsWith("/")?E:`${C}/${E}`,V=`${c}/${e("bench-out",L)}.json`,z=Bun.spawn(["bun",qe,L,V,JSON.stringify(v)],{cwd:C,stdout:"inherit",stderr:"inherit",stdin:"ignore"});P.add(z);let j=await z.exited;if(P.delete(z),j!==0)throw Error(`Bench suite failed: ${E} (runner exited ${j})`);N[H]=await t(V)},B=async()=>{while(M===void 0&&U<o.suites.length){let H=U++;try{await F(H)}catch(E){M??=E instanceof Error?E:Error(String(E));for(let L of P)L.kill()}}};try{if(await Promise.all(Array.from({length:Math.min(x,o.suites.length)},B)),M)throw M}finally{await Bun.spawn(["rm","-rf",c]).exited}let A=[],J=[];for(let H of N)A.push(...H.workloads),J.push(...H.runs);return r(A,J)}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 d(o,D,c=a){let C=new Set(D.workloads.map((v)=>v.id)),x=[];for(let v of o.workloads){if(!C.has(v.id))continue;let N=b(o,D,v.id,c);if(N)x.push(N)}return x}function b(o,D,c,C=a){let x=te(o,c,"timing"),v=te(D,c,"timing"),N=te(o,c,"cpu"),P=te(D,c,"cpu"),U=te(o,c,"heap"),M=te(D,c,"heap"),F=x?.id??N?.id??U?.id,B=v?.id??P?.id??M?.id;if(!F||!B)return;let A=!1,J;if(x?.timing&&v?.timing){let L=ie(x.timing.median,v.timing.median),V=ie(x.timing.mean,v.timing.mean),z=L>C.timingPct?"regressed":L<-C.timingPct?"improved":"unchanged";if(z==="regressed")A=!0;J={medianDeltaPct:L,meanDeltaPct:V,verdict:z}}let H;if(N?.cpu&&P?.cpu){let L=new Map(N.cpu.totals.map((O)=>[N.cpu.frames[O.frameIx].key,O])),V=new Map(P.cpu.totals.map((O)=>[P.cpu.frames[O.frameIx].key,O])),z=new Map(N.cpu.frames.map((O)=>[O.key,O.name])),j=new Map(P.cpu.frames.map((O)=>[O.key,O.name]));H=[...new Set([...L.keys(),...V.keys()])].map((O)=>{let S=L.get(O)?.selfUs??0,_=V.get(O)?.selfUs??0;return{frameKey:O,name:j.get(O)??z.get(O)??O,baseSelfUs:S,candSelfUs:_,deltaPct:ie(S,_)}}).sort((O,S)=>Math.abs(S.deltaPct)-Math.abs(O.deltaPct));for(let O of H)if((O.baseSelfUs>=C.minFrameSelfUs||O.candSelfUs>=C.minFrameSelfUs)&&O.deltaPct>C.frameSelfPct)A=!0}let E;if(U?.heap&&M?.heap){let L=new Map(U.heap.typeCounts.map((j)=>[j.type,j])),V=new Map(M.heap.typeCounts.map((j)=>[j.type,j]));E=[...new Set([...L.keys(),...V.keys()])].map((j)=>{let W=L.get(j),O=V.get(j);return{type:j,baseCount:W?.count??0,candCount:O?.count??0,baseBytes:W?.retainedBytes,candBytes:O?.retainedBytes,deltaPct:ie(W?.count??0,O?.count??0)}}).sort((j,W)=>Math.abs(W.deltaPct)-Math.abs(j.deltaPct));for(let j of E)if(j.deltaPct>C.heapTypePct)A=!0}return{id:e("cmp",F,B),baselineRunId:F,candidateRunId:B,timing:J,frames:H,heapTypes:E,thresholds:C,verdict:A?"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),x=new Int32Array(c).fill(-1);for(let U=0;U<c;U++)for(let M of D[U].children){let F=C(M);if(F!==-1)x[F]=U}let v=[];for(let U=0;U<c;U++)if(x[U]===-1)v.push(U);let N=[],P=[];for(let U=v.length-1;U>=0;U--)P.push(v[U]);while(P.length>0){let U=P.pop();N.push(U);for(let M of D[U].children){let F=C(M);if(F!==-1&&x[F]===U)P.push(F)}}return{count:c,indexOf:C,parentIx:x,roots:v,order:N}}function Xe(o){let D=o.nodes,c=D.length,C=1/0,x=-1/0,v=!0;for(let P=0;P<c;P++){let U=D[P].id;if(!Number.isInteger(U)){v=!1;break}if(U<C)C=U;if(U>x)x=U}if(v&&c>0&&x-C<c*4+64){let P=x-C+1,U=new Int32Array(P).fill(-1);for(let M=0;M<c;M++)U[D[M].id-C]=M;return(M)=>{let F=M-C;return F>=0&&F<P?U[F]:-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 xe(o,D){let{count:c,indexOf:C,parentIx:x,order:v}=D,N=new Float64Array(c),P=new Float64Array(c),U=o.samples?.nodeIds??[],M=o.samples?.timeDeltasUs??[];for(let B=0;B<U.length;B++){let A=C(U[B]);if(A===-1)continue;N[A]+=M[B]??0,P[A]+=1}let F=new Float64Array(c);for(let B=v.length-1;B>=0;B--){let A=v[B];F[A]+=N[A];let J=x[A];if(J>=0)F[J]+=F[A]}return{selfUs:N,totalUs:F,samples:P}}var Pe={name:"collapsed",async render(o,D={}){return{files:Z(o,D.runId).map((x)=>{let v=x.cpu,{nodes:N,frames:P}=v,U=re(v),M=Array(U.count);for(let H of U.order){let E=P[N[H].frameIx].name||"(anonymous)",L=U.parentIx[H];M[H]=L===-1?E:`${M[L]};${E}`}let F=new Float64Array(U.count),B=[],A=v.samples?.nodeIds??[];for(let H=0;H<A.length;H++){let E=U.indexOf(A[H]);if(E===-1)continue;if(F[E]++===0)B.push(E)}let J=Array(B.length);for(let H=0;H<B.length;H++){let E=B[H];J[H]=`${M[E]} ${F[E]}`}return{path:`${x.id}.collapsed.txt`,content:J.join(`
|
|
3
|
-
`)+(J.length>0?`
|
|
4
|
-
`:"")}})}}};var Te={name:"cpuprofile",async render(o,D={}){let c=Z(o,D.runId),C=[],x=[];for(let v of c){if(v.cpu?.origin!=="cpu-prof"&&v.cpu?.origin!=="inspector"){x.push(`${v.id} (origin ${v.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let N=v.artifacts.find((U)=>U.kind==="cpuprofile");if(!N){x.push(`${v.id} (no cpuprofile artifact recorded on this run)`);continue}let P=Bun.file(N.path);if(!await P.exists()){x.push(`${v.id} (artifact missing on disk: ${N.path})`);continue}C.push({path:`${v.id}.cpuprofile`,content:await P.text()})}if(C.length===0&&x.length>0)return{text:`No .cpuprofile artifacts available:
|
|
5
|
-
${x.map((v)=>` - ${v}`).join(`
|
|
6
|
-
`)}
|
|
7
|
-
`};return{files:C}}};var $e={name:"json",async render(o){return{text:y(o)}}};var ke={name:"jsonl",async render(o){let{runs:D,...c}=o;return{text:`${[g(c),...D.map((x)=>g(x))].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((x)=>[x.id,x])),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((x)=>x.phase==="timing"&&x.timing!==void 0);if(C.length>0){c.push("## Timing",""),c.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let v of C){let N=ae(D.get(v.workloadId)),P=v.timing;c.push(`| ${N} | ${ee(P.mean)} \xB1 ${ee(P.stddev)} | ${ee(P.min)}\u2026${ee(P.max)} | ${ee(P.median)} |`)}c.push("");let x=C.filter((v)=>v.warnings.length>0);if(x.length>0){c.push("### Warnings","");for(let v of x){let N=ae(D.get(v.workloadId));for(let P of v.warnings)c.push(`- **${N}**: ${P.message} (\`${P.code}\`)`)}c.push("")}}for(let x of o.runs){if(x.phase!=="cpu"&&x.phase!=="heap")continue;let v=ae(D.get(x.workloadId));if(x.phase==="cpu"){if(c.push(`## CPU capture - ${v}`,""),c.push(`instrumented, diagnostic wall ${ee(x.diagnosticWallNs??0)}ms`,""),x.cpu){c.push(`origin: \`${x.cpu.origin}\`, interval: ${x.cpu.samplingIntervalUs}\xB5s`,""),c.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let N=x.cpu.totals.reduce((P,U)=>P+U.selfUs,0)||1;for(let P of x.cpu.totals.slice(0,ve)){let U=x.cpu.frames[P.frameIx],M=(P.selfUs/N*100).toFixed(1);c.push(`| ${M}% | ${(P.selfUs/1000).toFixed(2)} | ${(P.totalUs/1000).toFixed(2)} | ${U?.name||"(anonymous)"} |`)}if(c.push(""),x.jit){let P=x.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 ${ee(x.diagnosticWallNs??0)}ms`,""),x.heap){c.push(`${x.heap.objectCount??"?"} objects, ${((x.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),c.push("| Count | Type |","|---|---|");for(let N of x.heap.typeCounts.slice(0,Ce))c.push(`| ${N.count} | ${N.type} |`);c.push("")}for(let N of x.artifacts)c.push(`- artifact: \`${N.path}\``);for(let N of x.warnings)c.push(`- ! ${N.message} (\`${N.code}\`)`);if(x.artifacts.length>0||x.warnings.length>0)c.push("")}if(o.comparisons&&o.comparisons.length>0){c.push("## Comparisons","");for(let x of o.comparisons){let v=o.runs.find((P)=>P.id===x.candidateRunId),N=ae(v?D.get(v.workloadId):void 0);if(c.push(`### ${x.verdict==="pass"?"\u2713":"\u2717"} ${N}`,""),x.timing){let P=x.timing.medianDeltaPct>0?"+":"";c.push(`- timing: ${P}${x.timing.medianDeltaPct.toFixed(1)}% median (**${x.timing.verdict}**)`)}for(let P of x.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 x.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 pe(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 x=[];if(C<=0)return x;for(let v=0;v<D;v++){if(v===c)continue;let N=o[v];if(x.length===C&&N<=o[x[C-1]])continue;let P=x.length;while(P>0&&o[x[P-1]]<N)P--;if(x.splice(P,0,v),x.length>C)x.pop()}return x}var Ie={name:"mermaid",async render(o,D={}){let c=D.topN??Ze;return{files:Z(o,D.runId).map((v)=>{let N=v.cpu,{nodes:P,frames:U}=N,M=re(N),{selfUs:F,totalUs:B}=xe(N,M),{parentIx:A}=M,J=M.roots[0]??-1,H=nn(F,M.count,J,c),E=new Set(J!==-1?[J]:[]),L=[];for(let z of H){L.length=0;for(let j=z;j!==-1;j=A[j])L.push(j);for(let j=L.length-1;j>=0;j--)E.add(L[j])}let V=["graph TD"];for(let z of E){let j=P[z].id;V.push(` ${pe(j)}["${en(U[P[z].frameIx].name,F[z],B[z])}"]`)}for(let z of E){let j=A[z];if(j!==-1&&E.has(j))V.push(` ${pe(P[j].id)} --> ${pe(P[z].id)}`)}return{path:`${v.id}.mermaid.md`,content:`${V.join(`
|
|
11
|
-
`)}
|
|
12
|
-
`}})}}};function Ue(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((x)=>x.run.timing.median)),c=new Map;for(let x of o){let v=Ue(x.workload);if(v===void 0)continue;let N=c.get(v);if(N)N.push(x);else c.set(v,[x])}let C=new Map;for(let x of o){let v=Ue(x.workload);if(v===void 0){C.set(x,D);continue}let N=c.get(v)??[x],P=N.find((U)=>U.workload?.baseline);C.set(x,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((v)=>[v.id,v])),c=o.runs.filter((v)=>v.phase==="timing"&&v.timing!==void 0).map((v)=>({run:v,workload:D.get(v.workloadId)})),C=c.length>1?ce(c):void 0,x=new Map((o.comparisons??[]).map((v)=>[v.candidateRunId,v]));return c.map((v)=>{let{run:N,workload:P}=v,U=N.timing,M={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((B)=>B.data?{code:B.code,data:B.data}:{code:B.code})};if(P?.entry?.group!==void 0)M.group=P.entry.group;if(P?.description!==void 0)M.description=P.description;if(P?.groupDescription!==void 0)M.groupDescription=P.groupDescription;if(C)M.relative=Q(U.median/(C.get(v)??U.median));if(P?.baseline)M.baseline=!0;let F=x.get(N.id);if(F?.timing)M.delta={medianPct:Q(F.timing.medianDeltaPct),meanPct:Q(F.timing.meanDeltaPct),verdict:F.timing.verdict,pass:F.verdict==="pass"};return M})}var De={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 Fe(o){return o?.label??o?.command?.join(" ")??o?.entry?.task??"profile"}var Me={name:"speedscope",async render(o,D={}){let c=Z(o,D.runId),C=new Map(o.workloads.map((v)=>[v.id,v]));return{files:c.map((v)=>{let N=v.cpu,{nodes:P}=N,U=re(N),M=N.samples?.nodeIds??[],F=N.samples?.timeDeltasUs??[],B=Array(U.count);for(let E of U.order){let L=U.parentIx[E],V=P[E].frameIx;B[E]=L===-1?[V]:[...B[L],V]}let A=Array(M.length);for(let E=0;E<M.length;E++){let L=U.indexOf(M[E]);A[E]=L===-1?[]:B[L]}let J=0;for(let E=0;E<F.length;E++)J+=F[E];let H={$schema:sn,exporter:"ostia",name:Fe(C.get(v.workloadId)),activeProfileIndex:0,shared:{frames:N.frames.map((E)=>({name:E.name||"(anonymous)",file:E.url,line:E.line!==void 0?E.line+1:void 0}))},profiles:[{type:"sampled",name:Fe(C.get(v.workloadId)),unit:"microseconds",startValue:0,endValue:J,samples:A,weights:F}]};return{path:`${v.id}.speedscope.json`,content:`${JSON.stringify(H,null,2)}
|
|
15
|
-
`}})}}};function se(o){return(o/1e6).toFixed(3)}function le(o){return o.label??o.command?.join(" ")??o.entry?.task??o.id}var Be={name:"table",async render(o){let D=o.runs.filter((B)=>B.phase==="timing"&&B.timing!==void 0),c=new Map(o.workloads.map((B)=>[B.id,B]));if(D.length===0){let B=Se(o,c);return{text:B.length>0?`${B.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`:`(no timing runs)
|
|
18
|
-
`}}let C=D.map((B)=>{let A=c.get(B.workloadId);return{run:B,workload:A,label:A?le(A):B.workloadId}}),x=C.length>1,v=ce(C),N=[],P=Math.max(7,...C.map((B)=>B.label.length)),U=x?`${"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 B of C){let{run:A,label:J,workload:H}=B,E=A.timing,L=`${se(E.mean)} \xB1 ${se(E.stddev)}`,V=`${se(E.min)}\u2026${se(E.max)}`,z=`${J.padEnd(P)} ${L.padEnd(15)} ${V.padEnd(18)}`;if(x){let j=E.median/(v.get(B)??E.median);if(j===1)z+=H?.baseline?" 1.00\xD7 (baseline)":" 1.00\xD7";else if(j>1)z+=` ${j.toFixed(2)}\xD7 slower`;else z+=` ${(1/j).toFixed(2)}\xD7 faster`}N.push(z);for(let j of A.warnings)N.push(` ! ${j.message}`)}let M=an(o,c);if(M.length>0)N.push(""),N.push(...M);let F=Se(o,c);if(F.length>0)N.push(""),N.push(...F);return{text:`${N.join(`
|
|
19
|
-
`)}
|
|
20
|
-
`}}};function on(o,D,c){let C=o.runs.find((v)=>v.id===c),x=C?D.get(C.workloadId):void 0;return x?le(x):c}function Se(o,D){if(!o.comparisons||o.comparisons.length===0)return[];let c=[];for(let C of o.comparisons){let x=on(o,D,C.candidateRunId),v=C.verdict==="pass"?"\u2713":"\u2717";if(c.push(`${v} ${x}`),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,Oe)){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,Oe=5;function an(o,D){let c=[];for(let C of o.runs){if(C.phase!=="cpu"&&C.phase!=="heap")continue;let x=D.get(C.workloadId),v=x?le(x):C.workloadId;if(C.phase==="cpu")if(C.cpu){c.push(`CPU capture - ${v} (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],M=(P.selfUs/N*100).toFixed(1);c.push(` ${M.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(C.heap){let N=((C.heap.heapSizeBytes??0)/1e6).toFixed(2);c.push(`Heap snapshot - ${v} (instrumented, ${C.heap.objectCount??"?"} objects, ${N}MB)`);for(let P of C.heap.typeCounts.slice(0,Oe))c.push(` ${String(P.count).padStart(6)} ${P.type}`)}else c.push(`Heap snapshot - ${v} (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:Be,json:$e,markdown:Ne,jsonl:ke,minimal:De,collapsed:Pe,mermaid:Ie,speedscope:Me,cpuprofile:Te};var cn="node_modules/.cache/ostia",me=1000;async function w(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`,x=[],v=[];for(let N of o.commands){let P=Array.isArray(N)?N:Re(N),U=u(P,Array.isArray(N)?void 0:N);x.push(U);let M=await f({argv:P,cwd:o.cwd,env:o.env,runs:o.runs,warmup:o.warmup}),F=i({workload:U,configFingerprint:D,trials:M.trials,timing:M.timing,warnings:M.warnings});if(v.push(F),o.cpu){let B=`${F.id}-cpu.cpuprofile`,A=await de({argv:P,cwd:o.cwd,env:o.env,artifactDir:C,fileName:B,intervalUs:o.cpuIntervalUs??me});v.push(await Ee({workload:U,phase:"cpu",configFingerprint:D,diagnosticWallNs:A.diagnosticWallNs,exitCode:A.exitCode,cpu:A.cpu,artifactPath:A.artifactPath,artifactKind:"cpuprofile",warnings:A.warnings}))}if(o.heap){let B=`${F.id}-heap.heapsnapshot`,A=await ge({argv:P,cwd:o.cwd,env:o.env,artifactDir:C,fileName:B});v.push(await Ee({workload:U,phase:"heap",configFingerprint:D,diagnosticWallNs:A.diagnosticWallNs,exitCode:A.exitCode,heap:A.heap,artifactPath:A.artifactPath,artifactKind:"heapsnapshot",warnings:A.warnings}))}}return r(x,v)}async function Ee(o){let D=`${o.workload.id}-${o.phase}-${o.configFingerprint}`,c=o.artifactPath?[await T(D,o.artifactKind,o.artifactPath)]:[];return h({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 I(o,D={}){let c=R(o),C=s({intervalUs:D.intervalUs??me,origin:D.origin??"inspector"}),x=(M)=>M.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(D.origin==="jsc"){let{result:M,cpu:F,jit:B,diagnosticWallNs:A}=await we(o,D),J=h({workload:c,phase:"cpu",configFingerprint:C,diagnosticWallNs:A,cpu:F,jit:B,warnings:x(F),artifacts:[]});return{result:M,run:J}}let{result:v,cpu:N,diagnosticWallNs:P}=await he(o,D),U=h({workload:c,phase:"cpu",configFingerprint:C,diagnosticWallNs:P,cpu:N,warnings:x(N),artifacts:[]});return{result:v,run:U}}
|
|
21
|
-
export{k,p,a,d,b,f,n,w,I};
|