ostia 0.1.0 → 0.1.1
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/chunk-ck12vbed.js +4 -0
- package/chunk-j0j2b0fj.js +19 -0
- package/cli.js +27 -44
- package/index.js +1 -18
- package/package.json +1 -1
- package/runner.ts +5 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
function N(n){return JSON.stringify(d(n))}function d(n){if(Array.isArray(n))return n.map(d);if(n!==null&&typeof n==="object"){let e={};for(let r of Object.keys(n).sort())e[r]=d(n[r]);return e}return n}function c(n,...e){let r=Bun.CryptoHasher.hash("sha256",N(e),"hex");return`${n}_${r.slice(0,16)}`}var k="0.1.0";function E(n,e){return{schemaVersion:1,toolVersion:k,bunVersion:Bun.version,platform:{os:process.platform,arch:process.arch},createdAt:new Date().toISOString(),workloads:n,runs:e}}function O(n,e){return{id:c("wl","subprocess",n,process.cwd()),kind:"subprocess",command:n,label:e}}function C(n,e){return{id:c("wl","inprocess",n.name,n.toString()),kind:"inprocess",label:e}}function q(n,e,r){return{id:c("wl","inprocess-entry",n,e),kind:"inprocess",entry:{file:n,task:e},label:r}}function _(n){return{id:c("run",n.workload.id,"timing",n.configFingerprint,Bun.version,k),workloadId:n.workload.id,phase:"timing",instrumented:!1,configFingerprint:n.configFingerprint,trials:n.trials,timing:n.timing,warnings:n.warnings,artifacts:[],memory:B(n.trials)}}function B(n){let e=n.map((r)=>r.maxRssBytes).filter((r)=>r!==void 0);if(e.length===0)return;return{origin:"resourceUsage",perTrial:n.map((r)=>({rssBytes:r.maxRssBytes})),maxRssBytes:Math.max(...e)}}function H(n){return{id:c("run",n.workload.id,n.phase,n.configFingerprint,Bun.version,k),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 J(n,e,r){let i=await Bun.file(r).arrayBuffer(),o=new Bun.CryptoHasher("sha256");return o.update(i),{id:c("art",n,e,r),kind:e,path:r,sha256:o.digest("hex"),bytes:i.byteLength}}function j(n){return c("cfg",n)}function D(n){return`${JSON.stringify(d(n),null,2)}
|
|
3
|
+
`}async function L(n,e){await Bun.write(e,D(n))}async function z(n){let e=await Bun.file(n).text();return JSON.parse(e)}var x=[],m;function K(n,e){let r=m;m=n;try{e()}finally{m=r}}function U(n,e){x.push({groupName:m,name:n,fn:e})}function G(){return x}function Z(){x.length=0,m=void 0}function X(n){if(n.length===0)throw Error("computeTimingStats: samples must be non-empty");let e=n.length,r=b(n),t=0;for(let a=0;a<e;a++)t+=n[a];let i=t/e,o=g(r,0.5),s=0;for(let a=0;a<e;a++){let u=n[a]-i;s+=u*u}let p=Math.sqrt(s/e),y=r[0],f=r[e-1],h=g(r,0.25),w=g(r,0.75),l=w-h,v=h-1.5*l,W=w+1.5*l,S=h-3*l,F=w+3*l,R=0,T=0;for(let a=0;a<e;a++){let u=n[a];if(u<S||u>F)T++;else if(u<v||u>W)R++}return{unit:"ns",samples:n,mean:i,median:o,stddev:p,min:y,max:f,outliers:{mild:R,severe:T}}}function b(n){let e=new Float64Array(n.length);return e.set(n),e.sort(),e}function g(n,e){let r=n.length;if(r===1)return n[0];let t=e*(r-1),i=Math.floor(t),o=Math.ceil(t);if(i===o)return n[i];let s=t-i;return n[i]*(1-s)+n[o]*s}var I=5000000,A=200;function Y(n,e,r="subprocess"){let t=[],i=n.samples[0];if(i!==void 0){let s=b(n.samples),p=g(s,0.25),f=g(s,0.75)-p;if(i>n.median+3*f&&f>0)t.push({code:"slow-first-run",message:`First run took ${(i/1e6).toFixed(2)}ms, much slower than the median ${(n.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:i,medianNs:n.median}})}if(n.outliers.mild+n.outliers.severe>0)t.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(r==="subprocess"&&n.median<I)t.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(r==="inprocess"&&n.median<A)t.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 o=e.filter((s)=>s!==void 0&&s!==0);if(o.length>0)t.push({code:"nonzero-exit",message:`${o.length} of ${e.length} trial(s) exited non-zero.`,data:{exitCodes:o}});return t}
|
|
4
|
+
export{N as i,c as j,k,E as l,O as m,C as n,q as o,_ as p,H as q,J as r,j as s,D as t,L as u,z as v,X as w,Y as x,K as y,U as z,G as A,Z as B};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{i as z,j as k,l as E,m as $e,n as Ce,p as Ie,q as j,r as Ne,s as G,t as pe,v as H,w as re,x as se}from"./chunk-ck12vbed.js";function Ue(e){return e.startsWith("file://")?e.slice(7):e}function W(e,a,n){let s=e.nodes,t=s.length,i=new Map,o=[],r=new Map,c=new Int32Array(t);for(let m=0;m<t;m++){let d=s[m],u=d.callFrame,y=Ue(u.url),T=i.get(u.functionName);if(T===void 0)T=new Map,i.set(u.functionName,T);let I=T.get(y);if(I===void 0)I=o.length,T.set(y,I),o.push({key:k("fr",u.functionName,y),name:u.functionName,url:y||void 0,line:u.lineNumber>=0?u.lineNumber:void 0,col:u.columnNumber>=0?u.columnNumber:void 0});c[m]=I,r.set(d.id,m)}let f=Array(t);for(let m=0;m<t;m++){let d=s[m];f[m]={id:d.id,frameIx:c[r.get(d.id)],children:d.children??[]}}let p=new Float64Array(t),l=new Float64Array(t),g=e.samples,x=e.timeDeltas;for(let m=0;m<g.length;m++){let d=r.get(g[m]);if(d===void 0)continue;p[d]+=x[m]??0,l[d]+=1}let R=new Int32Array(t).fill(-1);for(let m=0;m<t;m++){let d=s[m].children;if(!d)continue;for(let u of d){let y=r.get(u);if(y!==void 0)R[y]=m}}let h=[],w=[];for(let m=t-1;m>=0;m--)if(R[m]===-1)w.push(m);while(w.length>0){let m=w.pop();h.push(m);let d=s[m].children;if(!d)continue;for(let u of d){let y=r.get(u);if(y!==void 0&&R[y]===m)w.push(y)}}let P=new Float64Array(t);for(let m=h.length-1;m>=0;m--){let d=h[m];P[d]+=p[d];let u=R[d];if(u>=0)P[u]+=P[d]}let C=Array(o.length),b=[];for(let m=0;m<t;m++){let d=f[m].frameIx,u=C[d];if(u)u.selfUs+=p[m],u.totalUs+=P[m],u.samples+=l[m];else{let y={frameIx:d,selfUs:p[m],totalUs:P[m],samples:l[m]};C[d]=y,b.push(y)}}return{origin:a,samplingIntervalUs:n,frames:o,nodes:f,totals:b.sort((m,d)=>d.selfUs-m.selfUs),samples:{nodeIds:e.samples,timeDeltasUs:e.timeDeltas}}}function ve(e,a,n,s){let t=["--cpu-prof","--cpu-prof-dir",a,"--cpu-prof-name",n,"--cpu-prof-interval",String(s)],i=e[0];if(i==="bun"||i?.endsWith("/bun"))return[i,...t,...e.slice(1)];return e}async function Y(e){let a=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],s=n==="bun"||n?.endsWith("/bun"),t=ve(e.argv,e.artifactDir,e.fileName,e.intervalUs),i=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--cpu-prof --cpu-prof-dir ${e.artifactDir} --cpu-prof-name ${e.fileName} --cpu-prof-interval ${e.intervalUs}`},o=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:i,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,f=Bun.nanoseconds()-o,p=Bun.file(a);if(!await p.exists())return{diagnosticWallNs:f,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a .cpuprofile at ${a} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for CPU capture.`,data:{artifactPath:a,argv:e.argv}}]};let l=await p.json(),g=W(l,"cpu-prof",e.intervalUs),x=l.samples.length===0?[{code:"empty-profile",message:"CPU capture produced zero samples."}]:[];return{diagnosticWallNs:f,exitCode:c,artifactPath:a,cpu:g,warnings:x}}function q(e,a="heap-prof"){let{node_fields:n,node_types:s}=e.snapshot.meta,t=n.indexOf("type"),i=n.indexOf("self_size"),o=n.length,r=s[0];if(t===-1||i===-1||!Array.isArray(r))return{origin:a,typeCounts:[],objectCount:e.snapshot.node_count};let c=r.length,f=Array(c),p=new Map,l=[],g=0,x=e.nodes,R=x.length;for(let b=0;b<R;b+=o){let m=x[b+t],d=x[b+i]??0;g+=d;let u;if(m>=0&&m<c){if(u=f[m],u===void 0)u={type:r[m],count:0,bytes:0},f[m]=u,l.push(u)}else{let y=`unknown(${m})`;if(u=p.get(y),u===void 0)u={type:y,count:0,bytes:0},p.set(y,u),l.push(u)}u.count++,u.bytes+=d}let h=l.sort((b,m)=>m.count-b.count),w=h.slice(0,20),P=h.slice(20),C=w.map(({type:b,count:m,bytes:d})=>({type:b,count:m,retainedBytes:d}));if(P.length>0){let b=0,m=0;for(let d of P)b+=d.count,m+=d.bytes;C.push({type:"other",count:b,retainedBytes:m})}return{origin:a,heapSizeBytes:g,objectCount:e.snapshot.node_count,typeCounts:C}}function ke(e,a,n){let s=["--heap-prof","--heap-prof-dir",a,"--heap-prof-name",n],t=e[0];if(t==="bun"||t?.endsWith("/bun"))return[t,...s,...e.slice(1)];return e}async function Q(e){let a=`${e.artifactDir}/${e.fileName}`,n=e.argv[0],s=n==="bun"||n?.endsWith("/bun"),t=ke(e.argv,e.artifactDir,e.fileName),i=s?e.env:{...process.env,...e.env,BUN_OPTIONS:`--heap-prof --heap-prof-dir ${e.artifactDir} --heap-prof-name ${e.fileName}`},o=Bun.nanoseconds(),c=await Bun.spawn(t,{cwd:e.cwd,env:i,stdout:"ignore",stderr:"ignore",stdin:"ignore"}).exited,f=Bun.nanoseconds()-o,p=Bun.file(a);if(!await p.exists())return{diagnosticWallNs:f,exitCode:c,warnings:[{code:"artifact-missing",message:`Expected a heap snapshot at ${a} after exit ${c}, found nothing. The workload's argv[0] must be a \`bun\` binary for heap capture.`,data:{artifactPath:a,argv:e.argv}}]};let l=await p.json(),g=q(l,"heap-prof");return{diagnosticWallNs:f,exitCode:c,artifactPath:a,heap:g,warnings:[]}}import{Session as Fe}from"inspector/promises";var De=1000;async function X(e,a={}){let n=a.intervalUs??De,s=new Fe;s.connect();let t=Bun.nanoseconds();try{await s.post("Profiler.enable"),await s.post("Profiler.setSamplingInterval",{interval:n}),await s.post("Profiler.start");let i=await e(),{profile:o}=await s.post("Profiler.stop"),r=Bun.nanoseconds()-t,c=W(o,"inspector",n);return{result:i,cpu:c,diagnosticWallNs:r}}finally{s.disconnect()}}import{profile as Se}from"bun:jsc";var Me=new Map([["LLInt","llint"],["Baseline","baseline"],["DFG","dfg"],["FTL","ftl"]]),Z=4294967295;function ee(e,a){let n=a??e.interval*1e6,s=new Map,t=[];function i(u,y,T,I){let U=s.get(u);if(U===void 0)U=new Map,s.set(u,U);let N=y??"",v=U.get(N);if(v===void 0)v=t.length,U.set(N,v),t.push({key:k("fr",u,N),name:u,url:y,line:T,col:I});return v}function o(u){let y=u.line===Z,T=y?void 0:u.line-1,I=y||u.column===Z?void 0:u.column-1;return i(u.name,u.sourceURL,T,I)}let r=i("(root)",void 0,void 0,void 0),c=1,f={id:0,frameIx:r,children:new Map,selfUs:0,samples:0,totalUs:0},p=new Map([[0,f]]),l={llint:0,baseline:0,dfg:0,ftl:0},g=new Map,x=[],R=[];for(let u of e.traces){let y=u.frames,T=f;for(let N=y.length-1;N>=0;N--){let v=o(y[N]),M=T.children.get(v);if(!M)M={id:c++,frameIx:v,children:new Map,selfUs:0,samples:0,totalUs:0},T.children.set(v,M),p.set(M.id,M);T=M}T.selfUs+=n,T.samples+=1,x.push(T.id),R.push(n);let I=y[0],U=I&&Me.get(I.category);if(U){l[U]++;let N=g.get(U)??new Map;N.set(T.frameIx,(N.get(T.frameIx)??0)+1),g.set(U,N)}}function h(u){let y=u.selfUs;for(let T of u.children.values())y+=h(T);return u.totalUs=y,y}h(f);let w=new Map;function P(u){let y=w.get(u.frameIx);if(y)y.selfUs+=u.selfUs,y.totalUs+=u.totalUs,y.samples+=u.samples;else w.set(u.frameIx,{frameIx:u.frameIx,selfUs:u.selfUs,totalUs:u.totalUs,samples:u.samples});for(let T of u.children.values())P(T)}P(f);let C=[...p.values()].map((u)=>({id:u.id,frameIx:u.frameIx,children:[...u.children.values()].map((y)=>y.id)})),b={origin:"jsc-profile",samplingIntervalUs:n,frames:t,nodes:C,totals:[...w.values()].sort((u,y)=>y.selfUs-u.selfUs),samples:{nodeIds:x,timeDeltasUs:R}},m=[...g.entries()].flatMap(([u,y])=>[...y.entries()].sort((T,I)=>I[1]-T[1]).slice(0,3).map(([T,I])=>({tier:u,frameKey:t[T].key,samples:I})));return{cpu:b,jit:{origin:"jsc-profile",tiers:l,topFramesByTier:m}}}var Be=1000;async function ne(e,a={}){let n=a.intervalUs??Be,s,t=Bun.nanoseconds(),i=await Se(async()=>(s=await e(),s),n),o=Bun.nanoseconds()-t,{cpu:r,jit:c}=ee(i.stackTraces,n);return{result:s,cpu:r,jit:c,diagnosticWallNs:o}}async function L(e){let a=Bun.nanoseconds(),n=Bun.spawn(e.argv,{cwd:e.cwd,env:e.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),s=await n.exited,t=Bun.nanoseconds(),i=n.resourceUsage?.();return{wallNs:t-a,exitCode:s,userNs:i?Number(i.cpuTime.user)*1000:void 0,systemNs:i?Number(i.cpuTime.system)*1000:void 0,maxRssBytes:i?.maxRSS}}function te(e){return e.trim().split(/\s+/).filter(Boolean)}var Oe=10,We=3000000000,Ee=3;async function oe(e){let a=e.warmup??Ee;for(let p=0;p<a;p++)await L(e);let n=[],s=e.runs??e.minRuns??Oe,t=e.runs!==void 0?0:e.minTotalNs??We,i=0,o=0;while(o<s||i<t){let p=await L(e);if(n.push({i:o,wallNs:p.wallNs,exitCode:p.exitCode,userNs:p.userNs,systemNs:p.systemNs,maxRssBytes:p.maxRssBytes}),i+=p.wallNs,o++,e.runs!==void 0&&o>=e.runs)break}let r=n.map((p)=>p.wallNs),c=re(r),f=se(c,n.map((p)=>p.exitCode));return{trials:n,timing:c,warnings:f}}var Ae=new URL("./runner.ts",import.meta.url).pathname,_e=".ostia";async function je(e){let n=`${e.outDir??_e}/bench-tmp`,s=e.cwd??process.cwd(),t={timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc},i=[],o=[];try{for(let r of e.suites){let c=r.startsWith("/")?r:`${s}/${r}`,f=`${n}/${k("bench-out",c)}.json`,l=await Bun.spawn(["bun",Ae,c,f,JSON.stringify(t)],{cwd:s,stdout:"inherit",stderr:"inherit",stdin:"ignore"}).exited;if(l!==0)throw Error(`Bench suite failed: ${r} (runner exited ${l})`);let g=await H(f);i.push(...g.workloads),o.push(...g.runs)}}finally{await Bun.spawn(["rm","-rf",n]).exited}return E(i,o)}var ie={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function A(e,a){if(e===0)return a===0?0:1/0;return(a-e)/e*100}function S(e,a,n){return e.runs.find((s)=>s.workloadId===a&&s.phase===n)}function Le(e,a,n=ie){let s=new Set(a.workloads.map((i)=>i.id)),t=[];for(let i of e.workloads){if(!s.has(i.id))continue;let o=He(e,a,i.id,n);if(o)t.push(o)}return t}function He(e,a,n,s=ie){let t=S(e,n,"timing"),i=S(a,n,"timing"),o=S(e,n,"cpu"),r=S(a,n,"cpu"),c=S(e,n,"heap"),f=S(a,n,"heap"),p=t?.id??o?.id??c?.id,l=i?.id??r?.id??f?.id;if(!p||!l)return;let g=!1,x;if(t?.timing&&i?.timing){let w=A(t.timing.median,i.timing.median),P=A(t.timing.mean,i.timing.mean),C=w>s.timingPct?"regressed":w<-s.timingPct?"improved":"unchanged";if(C==="regressed")g=!0;x={medianDeltaPct:w,meanDeltaPct:P,verdict:C}}let R;if(o?.cpu&&r?.cpu){let w=new Map(o.cpu.totals.map((d)=>[o.cpu.frames[d.frameIx].key,d])),P=new Map(r.cpu.totals.map((d)=>[r.cpu.frames[d.frameIx].key,d])),C=new Map(o.cpu.frames.map((d)=>[d.key,d.name])),b=new Map(r.cpu.frames.map((d)=>[d.key,d.name]));R=[...new Set([...w.keys(),...P.keys()])].map((d)=>{let u=w.get(d)?.selfUs??0,y=P.get(d)?.selfUs??0;return{frameKey:d,name:b.get(d)??C.get(d)??d,baseSelfUs:u,candSelfUs:y,deltaPct:A(u,y)}}).sort((d,u)=>Math.abs(u.deltaPct)-Math.abs(d.deltaPct));for(let d of R)if((d.baseSelfUs>=s.minFrameSelfUs||d.candSelfUs>=s.minFrameSelfUs)&&d.deltaPct>s.frameSelfPct)g=!0}let h;if(c?.heap&&f?.heap){let w=new Map(c.heap.typeCounts.map((b)=>[b.type,b])),P=new Map(f.heap.typeCounts.map((b)=>[b.type,b]));h=[...new Set([...w.keys(),...P.keys()])].map((b)=>{let m=w.get(b),d=P.get(b);return{type:b,baseCount:m?.count??0,candCount:d?.count??0,baseBytes:m?.retainedBytes,candBytes:d?.retainedBytes,deltaPct:A(m?.count??0,d?.count??0)}}).sort((b,m)=>Math.abs(m.deltaPct)-Math.abs(b.deltaPct));for(let b of h)if(b.deltaPct>s.heapTypePct)g=!0}return{id:k("cmp",p,l),baselineRunId:p,candidateRunId:l,timing:x,frames:R,heapTypes:h,thresholds:s,verdict:g?"fail":"pass"}}function F(e,a){if(a){let n=e.runs.find((s)=>s.id===a);return n?.cpu?[n]:[]}return e.runs.filter((n)=>n.phase==="cpu"&&n.cpu)}function B(e){let a=e.nodes,n=a.length,s=ze(e),t=new Int32Array(n).fill(-1);for(let c=0;c<n;c++)for(let f of a[c].children){let p=s(f);if(p!==-1)t[p]=c}let i=[];for(let c=0;c<n;c++)if(t[c]===-1)i.push(c);let o=[],r=[];for(let c=i.length-1;c>=0;c--)r.push(i[c]);while(r.length>0){let c=r.pop();o.push(c);for(let f of a[c].children){let p=s(f);if(p!==-1&&t[p]===c)r.push(p)}}return{count:n,indexOf:s,parentIx:t,roots:i,order:o}}function ze(e){let a=e.nodes,n=a.length,s=1/0,t=-1/0,i=!0;for(let r=0;r<n;r++){let c=a[r].id;if(!Number.isInteger(c)){i=!1;break}if(c<s)s=c;if(c>t)t=c}if(i&&n>0&&t-s<n*4+64){let r=t-s+1,c=new Int32Array(r).fill(-1);for(let f=0;f<n;f++)c[a[f].id-s]=f;return(f)=>{let p=f-s;return p>=0&&p<r?c[p]:-1}}let o=new Map;for(let r=0;r<n;r++)o.set(a[r].id,r);return(r)=>o.get(r)??-1}function ae(e,a){let{count:n,indexOf:s,parentIx:t,order:i}=a,o=new Float64Array(n),r=new Float64Array(n),c=e.samples?.nodeIds??[],f=e.samples?.timeDeltasUs??[];for(let l=0;l<c.length;l++){let g=s(c[l]);if(g===-1)continue;o[g]+=f[l]??0,r[g]+=1}let p=new Float64Array(n);for(let l=i.length-1;l>=0;l--){let g=i[l];p[g]+=o[g];let x=t[g];if(x>=0)p[x]+=p[g]}return{selfUs:o,totalUs:p,samples:r}}var ce={name:"collapsed",async render(e,a={}){return{files:F(e,a.runId).map((t)=>{let i=t.cpu,{nodes:o,frames:r}=i,c=B(i),f=Array(c.count);for(let R of c.order){let h=r[o[R].frameIx].name||"(anonymous)",w=c.parentIx[R];f[R]=w===-1?h:`${f[w]};${h}`}let p=new Float64Array(c.count),l=[],g=i.samples?.nodeIds??[];for(let R=0;R<g.length;R++){let h=c.indexOf(g[R]);if(h===-1)continue;if(p[h]++===0)l.push(h)}let x=Array(l.length);for(let R=0;R<l.length;R++){let h=l[R];x[R]=`${f[h]} ${p[h]}`}return{path:`${t.id}.collapsed.txt`,content:x.join(`
|
|
3
|
+
`)+(x.length>0?`
|
|
4
|
+
`:"")}})}}};var ue={name:"cpuprofile",async render(e,a={}){let n=F(e,a.runId),s=[],t=[];for(let i of n){if(i.cpu?.origin!=="cpu-prof"&&i.cpu?.origin!=="inspector"){t.push(`${i.id} (origin ${i.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let o=i.artifacts.find((c)=>c.kind==="cpuprofile");if(!o){t.push(`${i.id} (no cpuprofile artifact recorded on this run)`);continue}let r=Bun.file(o.path);if(!await r.exists()){t.push(`${i.id} (artifact missing on disk: ${o.path})`);continue}s.push({path:`${i.id}.cpuprofile`,content:await r.text()})}if(s.length===0&&t.length>0)return{text:`No .cpuprofile artifacts available:
|
|
5
|
+
${t.map((i)=>` - ${i}`).join(`
|
|
6
|
+
`)}
|
|
7
|
+
`};return{files:s}}};var le={name:"json",async render(e){return{text:pe(e)}}};var me={name:"jsonl",async render(e){let{runs:a,...n}=e;return{text:`${[z(n),...a.map((t)=>z(t))].join(`
|
|
8
|
+
`)}
|
|
9
|
+
`}}};function D(e){return(e/1e6).toFixed(3)}function _(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??e?.id??"unknown"}var fe=10,de=10,ge={name:"markdown",async render(e){let a=new Map(e.workloads.map((t)=>[t.id,t])),n=[];n.push("# Profile Report",""),n.push(`Bun ${e.bunVersion} \xB7 ostia ${e.toolVersion} \xB7 ${e.platform.os}/${e.platform.arch} \xB7 ${e.createdAt}`,"");let s=e.runs.filter((t)=>t.phase==="timing"&&t.timing!==void 0);if(s.length>0){n.push("## Timing",""),n.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let i of s){let o=_(a.get(i.workloadId)),r=i.timing;n.push(`| ${o} | ${D(r.mean)} \xB1 ${D(r.stddev)} | ${D(r.min)}\u2026${D(r.max)} | ${D(r.median)} |`)}n.push("");let t=s.filter((i)=>i.warnings.length>0);if(t.length>0){n.push("### Warnings","");for(let i of t){let o=_(a.get(i.workloadId));for(let r of i.warnings)n.push(`- **${o}**: ${r.message} (\`${r.code}\`)`)}n.push("")}}for(let t of e.runs){if(t.phase!=="cpu"&&t.phase!=="heap")continue;let i=_(a.get(t.workloadId));if(t.phase==="cpu"){if(n.push(`## CPU capture - ${i}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.cpu){n.push(`origin: \`${t.cpu.origin}\`, interval: ${t.cpu.samplingIntervalUs}\xB5s`,""),n.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let o=t.cpu.totals.reduce((r,c)=>r+c.selfUs,0)||1;for(let r of t.cpu.totals.slice(0,fe)){let c=t.cpu.frames[r.frameIx],f=(r.selfUs/o*100).toFixed(1);n.push(`| ${f}% | ${(r.selfUs/1000).toFixed(2)} | ${(r.totalUs/1000).toFixed(2)} | ${c?.name||"(anonymous)"} |`)}if(n.push(""),t.jit){let r=t.jit.tiers;n.push(`JIT tiers: LLInt ${r.llint} \xB7 Baseline ${r.baseline} \xB7 DFG ${r.dfg} \xB7 FTL ${r.ftl}`,"")}}}else if(n.push(`## Heap snapshot - ${i}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.heap){n.push(`${t.heap.objectCount??"?"} objects, ${((t.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),n.push("| Count | Type |","|---|---|");for(let o of t.heap.typeCounts.slice(0,de))n.push(`| ${o.count} | ${o.type} |`);n.push("")}for(let o of t.artifacts)n.push(`- artifact: \`${o.path}\``);for(let o of t.warnings)n.push(`- ! ${o.message} (\`${o.code}\`)`);if(t.artifacts.length>0||t.warnings.length>0)n.push("")}if(e.comparisons&&e.comparisons.length>0){n.push("## Comparisons","");for(let t of e.comparisons){let i=e.runs.find((r)=>r.id===t.candidateRunId),o=_(i?a.get(i.workloadId):void 0);if(n.push(`### ${t.verdict==="pass"?"\u2713":"\u2717"} ${o}`,""),t.timing){let r=t.timing.medianDeltaPct>0?"+":"";n.push(`- timing: ${r}${t.timing.medianDeltaPct.toFixed(1)}% median (**${t.timing.verdict}**)`)}for(let r of t.frames?.slice(0,fe)??[]){if(Math.abs(r.deltaPct)<0.5)continue;let c=r.deltaPct>0?"+":"";n.push(`- frame \`${r.name}\`: ${c}${r.deltaPct.toFixed(1)}% self-time (${(r.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(r.candSelfUs/1000).toFixed(2)}ms)`)}for(let r of t.heapTypes?.slice(0,de)??[]){if(Math.abs(r.deltaPct)<0.5)continue;let c=r.deltaPct>0?"+":"";n.push(`- heap \`${r.type}\`: ${c}${r.deltaPct.toFixed(1)}% count (${r.baseCount} \u2192 ${r.candCount})`)}n.push("")}}return{text:n.join(`
|
|
10
|
+
`)}}};var Je=15;function J(e){return`n${e}`}function Ve(e,a,n){return`${(e||"(anonymous)").replace(/"/g,"'")} (self ${(a/1000).toFixed(2)}ms, total ${(n/1000).toFixed(2)}ms)`}function Ke(e,a,n,s){let t=[];if(s<=0)return t;for(let i=0;i<a;i++){if(i===n)continue;let o=e[i];if(t.length===s&&o<=e[t[s-1]])continue;let r=t.length;while(r>0&&e[t[r-1]]<o)r--;if(t.splice(r,0,i),t.length>s)t.pop()}return t}var he={name:"mermaid",async render(e,a={}){let n=a.topN??Je;return{files:F(e,a.runId).map((i)=>{let o=i.cpu,{nodes:r,frames:c}=o,f=B(o),{selfUs:p,totalUs:l}=ae(o,f),{parentIx:g}=f,x=f.roots[0]??-1,R=Ke(p,f.count,x,n),h=new Set(x!==-1?[x]:[]),w=[];for(let C of R){w.length=0;for(let b=C;b!==-1;b=g[b])w.push(b);for(let b=w.length-1;b>=0;b--)h.add(w[b])}let P=["graph TD"];for(let C of h){let b=r[C].id;P.push(` ${J(b)}["${Ve(c[r[C].frameIx].name,p[C],l[C])}"]`)}for(let C of h){let b=g[C];if(b!==-1&&h.has(b))P.push(` ${J(r[b].id)} --> ${J(r[C].id)}`)}return{path:`${i.id}.mermaid.md`,content:`${P.join(`
|
|
11
|
+
`)}
|
|
12
|
+
`}})}}};var Ge="https://www.speedscope.app/file-format-schema.json";function be(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var ye={name:"speedscope",async render(e,a={}){let n=F(e,a.runId),s=new Map(e.workloads.map((i)=>[i.id,i]));return{files:n.map((i)=>{let o=i.cpu,{nodes:r}=o,c=B(o),f=o.samples?.nodeIds??[],p=o.samples?.timeDeltasUs??[],l=Array(c.count);for(let h of c.order){let w=c.parentIx[h],P=r[h].frameIx;l[h]=w===-1?[P]:[...l[w],P]}let g=Array(f.length);for(let h=0;h<f.length;h++){let w=c.indexOf(f[h]);g[h]=w===-1?[]:l[w]}let x=0;for(let h=0;h<p.length;h++)x+=p[h];let R={$schema:Ge,exporter:"ostia",name:be(s.get(i.workloadId)),activeProfileIndex:0,shared:{frames:o.frames.map((h)=>({name:h.name||"(anonymous)",file:h.url,line:h.line!==void 0?h.line+1:void 0}))},profiles:[{type:"sampled",name:be(s.get(i.workloadId)),unit:"microseconds",startValue:0,endValue:x,samples:g,weights:p}]};return{path:`${i.id}.speedscope.json`,content:`${JSON.stringify(R,null,2)}
|
|
13
|
+
`}})}}};function O(e){return(e/1e6).toFixed(3)}function V(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var xe={name:"table",async render(e){let a=e.runs.filter((l)=>l.phase==="timing"&&l.timing!==void 0),n=new Map(e.workloads.map((l)=>[l.id,l]));if(a.length===0){let l=we(e,n);return{text:l.length>0?`${l.join(`
|
|
14
|
+
`)}
|
|
15
|
+
`:`(no timing runs)
|
|
16
|
+
`}}let s=a.map((l)=>{let g=n.get(l.workloadId);return{run:l,workload:g,label:g?V(g):l.workloadId}}),t=Math.min(...s.map((l)=>l.run.timing.median)),i=s.length>1,o=[],r=Math.max(7,...s.map((l)=>l.label.length)),c=i?`${"Command".padEnd(r)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(r)} Mean [ms] Min\u2026Max [ms]`;o.push(c),o.push("-".repeat(c.length));for(let{run:l,label:g}of s){let x=l.timing,R=`${O(x.mean)} \xB1 ${O(x.stddev)}`,h=`${O(x.min)}\u2026${O(x.max)}`,w=`${g.padEnd(r)} ${R.padEnd(15)} ${h.padEnd(18)}`;if(i){let P=x.median/t;w+=P===1?" 1.00\xD7":` ${P.toFixed(2)}\xD7 slower`}o.push(w);for(let P of l.warnings)o.push(` ! ${P.message}`)}let f=qe(e,n);if(f.length>0)o.push(""),o.push(...f);let p=we(e,n);if(p.length>0)o.push(""),o.push(...p);return{text:`${o.join(`
|
|
17
|
+
`)}
|
|
18
|
+
`}}};function Ye(e,a,n){let s=e.runs.find((i)=>i.id===n),t=s?a.get(s.workloadId):void 0;return t?V(t):n}function we(e,a){if(!e.comparisons||e.comparisons.length===0)return[];let n=[];for(let s of e.comparisons){let t=Ye(e,a,s.candidateRunId),i=s.verdict==="pass"?"\u2713":"\u2717";if(n.push(`${i} ${t}`),s.timing){let o=s.timing.medianDeltaPct>0?"+":"";n.push(` timing: ${o}${s.timing.medianDeltaPct.toFixed(1)}% median (${s.timing.verdict})`)}if(s.frames)for(let o of s.frames.slice(0,Re)){if(Math.abs(o.deltaPct)<0.5)continue;let r=o.deltaPct>0?"+":"";n.push(` frame ${o.name}: ${r}${o.deltaPct.toFixed(1)}% self-time (${(o.baseSelfUs/1000).toFixed(2)}ms -> ${(o.candSelfUs/1000).toFixed(2)}ms)`)}if(s.heapTypes)for(let o of s.heapTypes.slice(0,Pe)){if(Math.abs(o.deltaPct)<0.5)continue;let r=o.deltaPct>0?"+":"";n.push(` heap ${o.type}: ${r}${o.deltaPct.toFixed(1)}% count (${o.baseCount} -> ${o.candCount})`)}}return n}var Re=5,Pe=5;function qe(e,a){let n=[];for(let s of e.runs){if(s.phase!=="cpu"&&s.phase!=="heap")continue;let t=a.get(s.workloadId),i=t?V(t):s.workloadId;if(s.phase==="cpu")if(s.cpu){n.push(`CPU capture - ${i} (instrumented, ${s.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${O(s.diagnosticWallNs??0)}ms)`);let o=s.cpu.totals.reduce((r,c)=>r+c.selfUs,0)||1;for(let r of s.cpu.totals.slice(0,Re)){let c=s.cpu.frames[r.frameIx],f=(r.selfUs/o*100).toFixed(1);n.push(` ${f.padStart(5)}% ${(r.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else n.push(`CPU capture - ${i} (instrumented, no evidence captured)`);else if(s.heap){let o=((s.heap.heapSizeBytes??0)/1e6).toFixed(2);n.push(`Heap snapshot - ${i} (instrumented, ${s.heap.objectCount??"?"} objects, ${o}MB)`);for(let r of s.heap.typeCounts.slice(0,Pe))n.push(` ${String(r.count).padStart(6)} ${r.type}`)}else n.push(`Heap snapshot - ${i} (instrumented, no evidence captured)`);for(let o of s.artifacts)n.push(` artifact: ${o.path}`);for(let o of s.warnings)n.push(` ! ${o.message}`)}return n}var Qe={table:xe,json:le,markdown:ge,jsonl:me,collapsed:ce,mermaid:he,speedscope:ye,cpuprofile:ue};var Xe=".ostia",K=1000;async function st(e){let a=G({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??K}),s=`${e.outDir??Xe}/artifacts`,t=[],i=[];for(let o of e.commands){let r=Array.isArray(o)?o:te(o),c=$e(r,Array.isArray(o)?void 0:o);t.push(c);let f=await oe({argv:r,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),p=Ie({workload:c,configFingerprint:a,trials:f.trials,timing:f.timing,warnings:f.warnings});if(i.push(p),e.cpu){let l=`${p.id}-cpu.cpuprofile`,g=await Y({argv:r,cwd:e.cwd,env:e.env,artifactDir:s,fileName:l,intervalUs:e.cpuIntervalUs??K});i.push(await Te({workload:c,phase:"cpu",configFingerprint:a,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,cpu:g.cpu,artifactPath:g.artifactPath,artifactKind:"cpuprofile",warnings:g.warnings}))}if(e.heap){let l=`${p.id}-heap.heapsnapshot`,g=await Q({argv:r,cwd:e.cwd,env:e.env,artifactDir:s,fileName:l});i.push(await Te({workload:c,phase:"heap",configFingerprint:a,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,heap:g.heap,artifactPath:g.artifactPath,artifactKind:"heapsnapshot",warnings:g.warnings}))}}return E(t,i)}async function Te(e){let a=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,n=e.artifactPath?[await Ne(a,e.artifactKind,e.artifactPath)]:[];return j({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:n})}async function ot(e,a={}){let n=Ce(e),s=G({intervalUs:a.intervalUs??K,origin:a.origin??"inspector"}),t=(f)=>f.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(a.origin==="jsc"){let{result:f,cpu:p,jit:l,diagnosticWallNs:g}=await ne(e,a),x=j({workload:n,phase:"cpu",configFingerprint:s,diagnosticWallNs:g,cpu:p,jit:l,warnings:t(p),artifacts:[]});return{result:f,run:x}}let{result:i,cpu:o,diagnosticWallNs:r}=await X(e,a),c=j({workload:n,phase:"cpu",configFingerprint:s,diagnosticWallNs:r,cpu:o,warnings:t(o),artifacts:[]});return{result:i,run:c}}
|
|
19
|
+
export{je as a,ie as b,Le as c,He as d,oe as e,Qe as f,st as g,ot as h};
|
package/cli.js
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
|
|
4
|
-
`
|
|
5
|
-
`)+(b.length>0?`
|
|
6
|
-
`:"")}})}}};var $e={name:"cpuprofile",async render(e,n={}){let t=S(e,n.runId),s=[],r=[];for(let o of t){if(o.cpu?.origin!=="cpu-prof"&&o.cpu?.origin!=="inspector"){r.push(`${o.id} (origin ${o.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let i=o.artifacts.find((c)=>c.kind==="cpuprofile");if(!i){r.push(`${o.id} (no cpuprofile artifact recorded on this run)`);continue}let a=Bun.file(i.path);if(!await a.exists()){r.push(`${o.id} (artifact missing on disk: ${i.path})`);continue}s.push({path:`${o.id}.cpuprofile`,content:await a.text()})}if(s.length===0&&r.length>0)return{text:`No .cpuprofile artifacts available:
|
|
7
|
-
${r.map((o)=>` - ${o}`).join(`
|
|
3
|
+
import{a as z,b as R,c as _,d as v,e as M,f as m,g as K}from"./chunk-j0j2b0fj.js";import{j as y,k as O,l as U,m as H,p as q,s as J,u as b,v as g}from"./chunk-ck12vbed.js";function N(t){return y("cache",t.workloadId,t.phase,t.configFingerprint,t.bunVersion,t.toolVersion,t.instrumented,t.inputsDigest??null)}async function A(t,e=process.cwd()){if(t.length===0)return;let r=new Set;for(let s of t){let a=new Bun.Glob(s);for await(let i of a.scan({cwd:e,absolute:!1}))r.add(i)}let o=[...r].sort(),n=await Promise.all(o.map(async(s)=>{let a=await Bun.file(`${e}/${s}`).arrayBuffer();return{path:s,sha256:Bun.CryptoHasher.hash("sha256",a,"hex")}}));return y("inputs",n)}function E(t,e){return`${t}/cache/${e}.json`}async function I(t,e){let r=Bun.file(E(t,e));if(!await r.exists())return;return await r.json()}async function S(t,e,r){await Bun.write(E(t,e),`${JSON.stringify(r,null,2)}
|
|
4
|
+
`)}var G={runs:null,warmup:3,outDir:".ostia",baseline:"main",cpuIntervalUs:1000,thresholds:R,workloads:[]};async function B(t="ostia.config.json"){let e=Bun.file(t);if(!await e.exists())return;let r=await e.json();return{...G,...r,thresholds:{...R,...r.thresholds??{}}}}function T(t,e){return`${t.outDir}/baselines/${e??t.baseline}.json`}class x extends Error{path;constructor(t){super(`No baseline document at ${t}. Create one with: ostia run --export-json ${t} <command...>`);this.path=t}}async function L(t){let{config:e}=t,r=T(e,t.baselineName);if(!await Bun.file(r).exists())throw new x(r);let n=await g(r),s=[],a=0,i=0,d=0;for(let u of e.workloads){let h=H(u.command,u.label),Z=await A(u.inputs??[]),j=J({runs:e.runs,warmup:e.warmup}),D=N({workloadId:h.id,phase:"timing",configFingerprint:j,bunVersion:Bun.version,toolVersion:O,instrumented:!1,inputsDigest:Z}),F=t.full?void 0:await I(e.outDir,D),k,C;if(F)k=F,C="cached",i++;else{a++;let P=await M({argv:u.command,runs:e.runs??void 0,warmup:e.warmup});k=q({workload:h,configFingerprint:j,trials:P.trials,timing:P.timing,warnings:P.warnings}),await S(e.outDir,D,k),C="executed",d++}s.push({workload:h,status:C,run:k})}let c=U(s.map((u)=>u.workload),s.map((u)=>u.run)),l=0,f=0,p=0;for(let u of s){let h=v(n,c,u.workload.id,e.thresholds);if(!h){p++;continue}if(u.comparison=h,h.verdict==="pass")l++;else f++}return c.comparisons=s.map((u)=>u.comparison).filter((u)=>u!==void 0),{document:c,summary:{total:e.workloads.length,affected:a,cached:i,executed:d,passed:l,regressed:f,missingBaseline:p,results:s}}}function V(t){let e=[];if(e.push(`${t.total} workloads`),e.push(`${t.affected} affected by this change`),e.push(`${t.cached} cached`),e.push(`${t.executed} executed`),t.missingBaseline>0)e.push(`${t.missingBaseline} skipped (no matching baseline workload)`);let r=t.results.filter((o)=>o.comparison?.verdict==="fail").map((o)=>{let n=o.comparison.timing,s=o.workload.label??o.workload.command?.join(" ")??o.workload.id;return n?`${n.medianDeltaPct>0?"+":""}${n.medianDeltaPct.toFixed(1)}% median on ${s}`:s});return e.push(`${t.passed} passed ${t.regressed} regressed${r.length>0?` (${r.join(", ")})`:""}`),e.push(""),e.push(`Profile CI: ${t.regressed>0?"\u2717":"\u2713"}`),`${e.join(`
|
|
8
5
|
`)}
|
|
9
|
-
`}
|
|
10
|
-
`)}
|
|
11
|
-
|
|
12
|
-
`)}
|
|
13
|
-
`)}
|
|
14
|
-
`}})}}};var Rn="https://www.speedscope.app/file-format-schema.json";function Se(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var Be={name:"speedscope",async render(e,n={}){let t=S(e,n.runId),s=new Map(e.workloads.map((o)=>[o.id,o]));return{files:t.map((o)=>{let i=o.cpu,{nodes:a}=i,c=j(i),l=i.samples?.nodeIds??[],u=i.samples?.timeDeltasUs??[],p=Array(c.count);for(let w of c.order){let R=c.parentIx[w],k=a[w].frameIx;p[w]=R===-1?[k]:[...p[R],k]}let d=Array(l.length);for(let w=0;w<l.length;w++){let R=c.indexOf(l[w]);d[w]=R===-1?[]:p[R]}let b=0;for(let w=0;w<u.length;w++)b+=u[w];let x={$schema:Rn,exporter:"ostia",name:Se(s.get(o.workloadId)),activeProfileIndex:0,shared:{frames:i.frames.map((w)=>({name:w.name||"(anonymous)",file:w.url,line:w.line!==void 0?w.line+1:void 0}))},profiles:[{type:"sampled",name:Se(s.get(o.workloadId)),unit:"microseconds",startValue:0,endValue:b,samples:d,weights:u}]};return{path:`${o.id}.speedscope.json`,content:`${JSON.stringify(x,null,2)}
|
|
15
|
-
`}})}}};function z(e){return(e/1e6).toFixed(3)}function ue(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var Me={name:"table",async render(e){let n=e.runs.filter((p)=>p.phase==="timing"&&p.timing!==void 0),t=new Map(e.workloads.map((p)=>[p.id,p]));if(n.length===0){let p=Ae(e,t);return{text:p.length>0?`${p.join(`
|
|
16
|
-
`)}
|
|
17
|
-
`:`(no timing runs)
|
|
18
|
-
`}}let s=n.map((p)=>{let d=t.get(p.workloadId);return{run:p,workload:d,label:d?ue(d):p.workloadId}}),r=Math.min(...s.map((p)=>p.run.timing.median)),o=s.length>1,i=[],a=Math.max(7,...s.map((p)=>p.label.length)),c=o?`${"Command".padEnd(a)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(a)} Mean [ms] Min\u2026Max [ms]`;i.push(c),i.push("-".repeat(c.length));for(let{run:p,label:d}of s){let b=p.timing,x=`${z(b.mean)} \xB1 ${z(b.stddev)}`,w=`${z(b.min)}\u2026${z(b.max)}`,R=`${d.padEnd(a)} ${x.padEnd(15)} ${w.padEnd(18)}`;if(o){let k=b.median/r;R+=k===1?" 1.00\xD7":` ${k.toFixed(2)}\xD7 slower`}i.push(R);for(let k of p.warnings)i.push(` ! ${k.message}`)}let l=Pn(e,t);if(l.length>0)i.push(""),i.push(...l);let u=Ae(e,t);if(u.length>0)i.push(""),i.push(...u);return{text:`${i.join(`
|
|
19
|
-
`)}
|
|
20
|
-
`}}};function kn(e,n,t){let s=e.runs.find((o)=>o.id===t),r=s?n.get(s.workloadId):void 0;return r?ue(r):t}function Ae(e,n){if(!e.comparisons||e.comparisons.length===0)return[];let t=[];for(let s of e.comparisons){let r=kn(e,n,s.candidateRunId),o=s.verdict==="pass"?"\u2713":"\u2717";if(t.push(`${o} ${r}`),s.timing){let i=s.timing.medianDeltaPct>0?"+":"";t.push(` timing: ${i}${s.timing.medianDeltaPct.toFixed(1)}% median (${s.timing.verdict})`)}if(s.frames)for(let i of s.frames.slice(0,Ee)){if(Math.abs(i.deltaPct)<0.5)continue;let a=i.deltaPct>0?"+":"";t.push(` frame ${i.name}: ${a}${i.deltaPct.toFixed(1)}% self-time (${(i.baseSelfUs/1000).toFixed(2)}ms -> ${(i.candSelfUs/1000).toFixed(2)}ms)`)}if(s.heapTypes)for(let i of s.heapTypes.slice(0,Oe)){if(Math.abs(i.deltaPct)<0.5)continue;let a=i.deltaPct>0?"+":"";t.push(` heap ${i.type}: ${a}${i.deltaPct.toFixed(1)}% count (${i.baseCount} -> ${i.candCount})`)}}return t}var Ee=5,Oe=5;function Pn(e,n){let t=[];for(let s of e.runs){if(s.phase!=="cpu"&&s.phase!=="heap")continue;let r=n.get(s.workloadId),o=r?ue(r):s.workloadId;if(s.phase==="cpu")if(s.cpu){t.push(`CPU capture - ${o} (instrumented, ${s.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${z(s.diagnosticWallNs??0)}ms)`);let i=s.cpu.totals.reduce((a,c)=>a+c.selfUs,0)||1;for(let a of s.cpu.totals.slice(0,Ee)){let c=s.cpu.frames[a.frameIx],l=(a.selfUs/i*100).toFixed(1);t.push(` ${l.padStart(5)}% ${(a.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else t.push(`CPU capture - ${o} (instrumented, no evidence captured)`);else if(s.heap){let i=((s.heap.heapSizeBytes??0)/1e6).toFixed(2);t.push(`Heap snapshot - ${o} (instrumented, ${s.heap.objectCount??"?"} objects, ${i}MB)`);for(let a of s.heap.typeCounts.slice(0,Oe))t.push(` ${String(a.count).padStart(6)} ${a.type}`)}else t.push(`Heap snapshot - ${o} (instrumented, no evidence captured)`);for(let i of s.artifacts)t.push(` artifact: ${i.path}`);for(let i of s.warnings)t.push(` ! ${i.message}`)}return t}var I={table:Me,json:Ne,markdown:ve,jsonl:Ie,collapsed:Te,mermaid:Ue,speedscope:Be,cpuprofile:$e};var Cn=".ostia",le=1000;async function We(e){let n=H({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??le}),s=`${e.outDir??Cn}/artifacts`,r=[],o=[];for(let i of e.commands){let a=Array.isArray(i)?i:xe(i),c=G(a,Array.isArray(i)?void 0:i);r.push(c);let l=await Q({argv:a,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),u=Z({workload:c,configFingerprint:n,trials:l.trials,timing:l.timing,warnings:l.warnings});if(o.push(u),e.cpu){let p=`${u.id}-cpu.cpuprofile`,d=await pe({argv:a,cwd:e.cwd,env:e.env,artifactDir:s,fileName:p,intervalUs:e.cpuIntervalUs??le});o.push(await je({workload:c,phase:"cpu",configFingerprint:n,diagnosticWallNs:d.diagnosticWallNs,exitCode:d.exitCode,cpu:d.cpu,artifactPath:d.artifactPath,artifactKind:"cpuprofile",warnings:d.warnings}))}if(e.heap){let p=`${u.id}-heap.heapsnapshot`,d=await de({argv:a,cwd:e.cwd,env:e.env,artifactDir:s,fileName:p});o.push(await je({workload:c,phase:"heap",configFingerprint:n,diagnosticWallNs:d.diagnosticWallNs,exitCode:d.exitCode,heap:d.heap,artifactPath:d.artifactPath,artifactKind:"heapsnapshot",warnings:d.warnings}))}}return M(r,o)}async function je(e){let n=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,t=e.artifactPath?[await ye(n,e.artifactKind,e.artifactPath)]:[];return Y({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:t})}async function Yt(e,n={}){let t=we(e),s=H({intervalUs:n.intervalUs??le,origin:n.origin??"inspector"}),r=(l)=>l.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(n.origin==="jsc"){let{result:l,cpu:u,jit:p,diagnosticWallNs:d}=await be(e,n),b=Y({workload:t,phase:"cpu",configFingerprint:s,diagnosticWallNs:d,cpu:u,jit:p,warnings:r(u),artifacts:[]});return{result:l,run:b}}let{result:o,cpu:i,diagnosticWallNs:a}=await fe(e,n),c=Y({workload:t,phase:"cpu",configFingerprint:s,diagnosticWallNs:a,cpu:i,warnings:r(i),artifacts:[]});return{result:o,run:c}}function _e(e){return T("cache",e.workloadId,e.phase,e.configFingerprint,e.bunVersion,e.toolVersion,e.instrumented,e.inputsDigest??null)}async function He(e,n=process.cwd()){if(e.length===0)return;let t=new Set;for(let o of e){let i=new Bun.Glob(o);for await(let a of i.scan({cwd:n,absolute:!1}))t.add(a)}let s=[...t].sort(),r=await Promise.all(s.map(async(o)=>{let i=await Bun.file(`${n}/${o}`).arrayBuffer();return{path:o,sha256:Bun.CryptoHasher.hash("sha256",i,"hex")}}));return T("inputs",r)}function Le(e,n){return`${e}/cache/${n}.json`}async function Je(e,n){let t=Bun.file(Le(e,n));if(!await t.exists())return;return await t.json()}async function ze(e,n,t){await Bun.write(Le(e,n),`${JSON.stringify(t,null,2)}
|
|
21
|
-
`)}var Tn={runs:null,warmup:3,outDir:".ostia",baseline:"main",cpuIntervalUs:1000,thresholds:J,workloads:[]};async function Ve(e="ostia.config.json"){let n=Bun.file(e);if(!await n.exists())return;let t=await n.json();return{...Tn,...t,thresholds:{...J,...t.thresholds??{}}}}function qe(e,n){return`${e.outDir}/baselines/${n??e.baseline}.json`}class te extends Error{path;constructor(e){super(`No baseline document at ${e}. Create one with: ostia run --export-json ${e} <command...>`);this.path=e}}async function Ke(e){let{config:n}=e,t=qe(n,e.baselineName);if(!await Bun.file(t).exists())throw new te(t);let r=await v(t),o=[],i=0,a=0,c=0;for(let b of n.workloads){let x=G(b.command,b.label),w=await He(b.inputs??[]),R=H({runs:n.runs,warmup:n.warmup}),k=_e({workloadId:x.id,phase:"timing",configFingerprint:R,bunVersion:Bun.version,toolVersion:_,instrumented:!1,inputsDigest:w}),P=e.full?void 0:await Je(n.outDir,k),h,m;if(P)h=P,m="cached",a++;else{i++;let g=await Q({argv:b.command,runs:n.runs??void 0,warmup:n.warmup});h=Z({workload:x,configFingerprint:R,trials:g.trials,timing:g.timing,warnings:g.warnings}),await ze(n.outDir,k,h),m="executed",c++}o.push({workload:x,status:m,run:h})}let l=M(o.map((b)=>b.workload),o.map((b)=>b.run)),u=0,p=0,d=0;for(let b of o){let x=ae(r,l,b.workload.id,n.thresholds);if(!x){d++;continue}if(b.comparison=x,x.verdict==="pass")u++;else p++}return l.comparisons=o.map((b)=>b.comparison).filter((b)=>b!==void 0),{document:l,summary:{total:n.workloads.length,affected:i,cached:a,executed:c,passed:u,regressed:p,missingBaseline:d,results:o}}}function Ge(e){let n=[];if(n.push(`${e.total} workloads`),n.push(`${e.affected} affected by this change`),n.push(`${e.cached} cached`),n.push(`${e.executed} executed`),e.missingBaseline>0)n.push(`${e.missingBaseline} skipped (no matching baseline workload)`);let t=e.results.filter((s)=>s.comparison?.verdict==="fail").map((s)=>{let r=s.comparison.timing,o=s.workload.label??s.workload.command?.join(" ")??s.workload.id;return r?`${r.medianDeltaPct>0?"+":""}${r.medianDeltaPct.toFixed(1)}% median on ${o}`:o});return n.push(`${e.passed} passed ${e.regressed} regressed${t.length>0?` (${t.join(", ")})`:""}`),n.push(""),n.push(`Profile CI: ${e.regressed>0?"\u2717":"\u2713"}`),`${n.join(`
|
|
22
|
-
`)}
|
|
23
|
-
`}async function V(e,n){if(e.text)process.stdout.write(e.text);if(!e.files||e.files.length===0)return;if(n)for(let t of e.files){let s=t.path?`${n}/${t.path}`:n;await Bun.write(s,t.content),process.stdout.write(`wrote ${s}
|
|
24
|
-
`)}else if(e.files.length===1)process.stdout.write(e.files[0].content);else for(let t of e.files)process.stdout.write(`--- ${t.path??"(unnamed)"} ---
|
|
25
|
-
${t.content}
|
|
26
|
-
`)}var $n=`ostia run [flags] <command...>
|
|
6
|
+
`}async function w(t,e){if(t.text)process.stdout.write(t.text);if(!t.files||t.files.length===0)return;if(e)for(let r of t.files){let o=r.path?`${e}/${r.path}`:e;await Bun.write(o,r.content),process.stdout.write(`wrote ${o}
|
|
7
|
+
`)}else if(t.files.length===1)process.stdout.write(t.files[0].content);else for(let r of t.files)process.stdout.write(`--- ${r.path??"(unnamed)"} ---
|
|
8
|
+
${r.content}
|
|
9
|
+
`)}var Q=`ostia run [flags] <command...>
|
|
27
10
|
|
|
28
11
|
Run one or more commands N times with warmup and report timing statistics.
|
|
29
12
|
|
|
@@ -47,7 +30,7 @@ Examples:
|
|
|
47
30
|
ostia run --runs 25 --warmup 3 "bun a.ts" "bun b.ts"
|
|
48
31
|
ostia run --cpu --heap "bun src/server.ts"
|
|
49
32
|
ostia run --format json "bun a.ts"
|
|
50
|
-
`,
|
|
33
|
+
`,X=`ostia bench [flags] <suite.ts...>
|
|
51
34
|
|
|
52
35
|
Run in-process benchmark suites (registered via group()/task()). Each suite file runs
|
|
53
36
|
in its own spawned child process (isolated from CLI startup state).
|
|
@@ -71,7 +54,7 @@ Suite files register tasks like:
|
|
|
71
54
|
Examples:
|
|
72
55
|
ostia bench benches/parse.ts
|
|
73
56
|
ostia bench --time-budget 1000 --min-samples 50 benches/*.ts
|
|
74
|
-
`,
|
|
57
|
+
`,W=`ostia compare <base.json> <candidate.json>
|
|
75
58
|
ostia compare <candidate.json> --baseline <path.json>
|
|
76
59
|
|
|
77
60
|
Compare two ProfileDocuments (matched by workload id) and rank timing/frame/heap deltas.
|
|
@@ -85,10 +68,10 @@ Flags:
|
|
|
85
68
|
Examples:
|
|
86
69
|
ostia compare before.json after.json
|
|
87
70
|
ostia compare after.json --baseline .ostia/baselines/main.json
|
|
88
|
-
`,
|
|
71
|
+
`,Y=`ostia report <document.json> [--format table|json|markdown|jsonl]
|
|
89
72
|
|
|
90
73
|
Render a saved ProfileDocument.
|
|
91
|
-
`,
|
|
74
|
+
`,ee=`ostia viz <document.json> --format FORMAT [--run <id>] [--out-dir PATH]
|
|
92
75
|
|
|
93
76
|
Render CPU evidence from a saved ProfileDocument as a visualization artifact. Files,
|
|
94
77
|
not a GUI - hand the output to speedscope.app, flamegraph.pl, or
|
|
@@ -109,7 +92,7 @@ Flags:
|
|
|
109
92
|
Examples:
|
|
110
93
|
ostia viz run.json --format speedscope --out-dir .ostia/viz
|
|
111
94
|
ostia viz run.json --format collapsed | flamegraph.pl > flame.svg
|
|
112
|
-
`,
|
|
95
|
+
`,te=`ostia ci [--full] [--baseline NAME]
|
|
113
96
|
|
|
114
97
|
Load ostia.config.json, run configured workloads (reusing cached results when their
|
|
115
98
|
fingerprint is unchanged), compare against the named baseline, and gate on regressions.
|
|
@@ -122,21 +105,21 @@ Flags:
|
|
|
122
105
|
--help show this message
|
|
123
106
|
|
|
124
107
|
Exit codes: 0 pass, 1 regression, 2 harness error (missing config/baseline, spawn failure).
|
|
125
|
-
`;function
|
|
126
|
-
`),2;let
|
|
127
|
-
`),2}if(
|
|
128
|
-
`),2;let
|
|
129
|
-
`),2}if(
|
|
130
|
-
`),2}let
|
|
131
|
-
`),2}let
|
|
132
|
-
`),2;let
|
|
133
|
-
`),2}let
|
|
108
|
+
`;function re(t){let e=[],r,o,n=!1,s=!1,a,i,d,c="table",l=!1,f=!1;for(let p=0;p<t.length;p++){let u=t[p];switch(u){case"--runs":r=Number(t[++p]);break;case"--warmup":o=Number(t[++p]);break;case"--cpu":n=!0;break;case"--heap":s=!0;break;case"--cpu-interval":a=Number(t[++p]);break;case"--out-dir":i=t[++p];break;case"--export-json":d=t[++p];break;case"--format":c=t[++p];break;case"--quiet":l=!0;break;case"--help":case"-h":f=!0;break;default:e.push(u)}}return{commands:e,runs:r,warmup:o,cpu:n,heap:s,cpuIntervalUs:a,outDir:i,exportJson:d,format:c,quiet:l,help:f}}async function ne(t){let e=re(t);if(e.help||e.commands.length===0)return process.stdout.write(Q),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}
|
|
109
|
+
`),2;let r;try{r=await K({commands:e.commands,runs:e.runs,warmup:e.warmup,cpu:e.cpu,heap:e.heap,cpuIntervalUs:e.cpuIntervalUs,outDir:e.outDir})}catch(n){return process.stderr.write(`Run failed: ${n instanceof Error?n.message:String(n)}
|
|
110
|
+
`),2}if(e.exportJson)await b(r,e.exportJson);if(!e.quiet){let s=await m[e.format].render(r,{});await w(s)}return r.runs.some((n)=>n.trials.some((s)=>s.exitCode!==void 0&&s.exitCode!==0))?1:0}function se(t){let e=[],r,o,n=!1,s,a,i="table",d=!1,c=!1;for(let l=0;l<t.length;l++){let f=t[l];switch(f){case"--time-budget":r=Number(t[++l]);break;case"--min-samples":o=Number(t[++l]);break;case"--gc":n=!0;break;case"--out-dir":s=t[++l];break;case"--export-json":a=t[++l];break;case"--format":i=t[++l];break;case"--quiet":d=!0;break;case"--help":case"-h":c=!0;break;default:e.push(f)}}return{suites:e,timeBudgetMs:r,minSamples:o,gc:n,outDir:s,exportJson:a,format:i,quiet:d,help:c}}async function oe(t){let e=se(t);if(e.help||e.suites.length===0)return process.stdout.write(X),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}
|
|
111
|
+
`),2;let r;try{r=await z({suites:e.suites,timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc,outDir:e.outDir})}catch(o){return process.stderr.write(`Bench failed: ${o instanceof Error?o.message:String(o)}
|
|
112
|
+
`),2}if(e.exportJson)await b(r,e.exportJson);if(!e.quiet){let n=await m[e.format].render(r,{});await w(n)}return 0}function ae(t){let e=[],r,o,n="table",s=!1,a=!1;for(let i=0;i<t.length;i++){let d=t[i];switch(d){case"--baseline":r=t[++i];break;case"--export-json":o=t[++i];break;case"--format":n=t[++i];break;case"--quiet":s=!0;break;case"--help":case"-h":a=!0;break;default:e.push(d)}}return{paths:e,baseline:r,exportJson:o,format:n,quiet:s,help:a}}async function ie(t){let e=ae(t);if(e.help)return process.stdout.write(W),0;let r,o;if(e.baseline)r=e.baseline,o=e.paths[0];else r=e.paths[0],o=e.paths[1];if(!r||!o)return process.stdout.write(W),2;let n,s;try{[n,s]=await Promise.all([g(r),g(o)])}catch(c){return process.stderr.write(`Failed to load documents: ${c instanceof Error?c.message:String(c)}
|
|
113
|
+
`),2}let a=_(n,s),i={...s,comparisons:a};if(e.exportJson)await b(i,e.exportJson);if(!e.quiet){let l=await m[e.format].render(i,{});await w(l)}return a.some((c)=>c.verdict==="fail")?1:0}function ue(t){let e,r="table",o=!1;for(let n=0;n<t.length;n++){let s=t[n];switch(s){case"--format":r=t[++n];break;case"--help":case"-h":o=!0;break;default:e=s}}return{path:e,format:r,help:o}}async function ce(t){let e=ue(t);if(e.help||!e.path)return process.stdout.write(Y),e.help?0:2;let r;try{r=await g(e.path)}catch(s){return process.stderr.write(`Failed to load ${e.path}: ${s instanceof Error?s.message:String(s)}
|
|
114
|
+
`),2}let n=await m[e.format].render(r,{});return await w(n),0}var le={ascii:"table"};function de(t){let e,r,o,n,s=!1;for(let a=0;a<t.length;a++){let i=t[a];switch(i){case"--format":{let d=t[++a]??"";r=le[d]??d;break}case"--run":o=t[++a];break;case"--out-dir":n=t[++a];break;case"--help":case"-h":s=!0;break;default:e=i}}return{path:e,format:r,runId:o,outDir:n,help:s}}async function pe(t){let e=de(t);if(e.help||!e.path||!e.format)return process.stdout.write(ee),e.help?0:2;if(!(e.format in m))return process.stderr.write(`Unknown --format "${e.format}". Expected one of: ${Object.keys(m).join(", ")}, ascii
|
|
115
|
+
`),2;let r;try{r=await g(e.path)}catch(s){return process.stderr.write(`Failed to load ${e.path}: ${s instanceof Error?s.message:String(s)}
|
|
116
|
+
`),2}let n=await m[e.format].render(r,{runId:e.runId});if(!n.text&&(!n.files||n.files.length===0))return process.stderr.write(e.runId?`No CPU evidence found for run "${e.runId}".
|
|
134
117
|
`:`No CPU evidence found in this document (no cpu-phase runs). Capture some with "ostia run --cpu ...".
|
|
135
|
-
`),2;return await
|
|
136
|
-
`),2;if(
|
|
137
|
-
`),2;let
|
|
138
|
-
`),2;return process.stderr.write(`CI run failed: ${
|
|
139
|
-
`),2}if(
|
|
118
|
+
`),2;return await w(n,e.outDir),0}function me(t){let e=!1,r,o,n=!1,s=!1;for(let a=0;a<t.length;a++)switch(t[a]){case"--full":e=!0;break;case"--baseline":r=t[++a];break;case"--export-json":o=t[++a];break;case"--quiet":n=!0;break;case"--help":case"-h":s=!0;break}return{full:e,baseline:r,exportJson:o,quiet:n,help:s}}async function fe(t){let e=me(t);if(e.help)return process.stdout.write(te),0;let r=await B();if(!r)return process.stderr.write(`No ostia.config.json found. "ostia ci" needs configured workloads.
|
|
119
|
+
`),2;if(r.workloads.length===0)return process.stderr.write(`ostia.config.json has no "workloads" configured.
|
|
120
|
+
`),2;let o;try{o=await L({config:r,full:e.full,baselineName:e.baseline})}catch(n){if(n instanceof x)return process.stderr.write(`${n.message}
|
|
121
|
+
`),2;return process.stderr.write(`CI run failed: ${n instanceof Error?n.message:String(n)}
|
|
122
|
+
`),2}if(e.exportJson)await b(o.document,e.exportJson);if(!e.quiet)process.stdout.write(V(o.summary));return o.summary.regressed>0?1:0}async function he(){let[t,...e]=process.argv.slice(2);switch(t){case"run":return ne(e);case"bench":return oe(e);case"compare":return ie(e);case"report":return ce(e);case"ci":return fe(e);case"viz":return pe(e);case void 0:case"--help":case"-h":return process.stdout.write(`ostia - Bun-native profile IR engine
|
|
140
123
|
|
|
141
124
|
Commands:
|
|
142
125
|
run Run commands N times and report timing/CPU/heap
|
|
@@ -147,5 +130,5 @@ Commands:
|
|
|
147
130
|
viz Render CPU evidence as collapsed/mermaid/speedscope/cpuprofile
|
|
148
131
|
|
|
149
132
|
Run "ostia <command> --help" for details.
|
|
150
|
-
`),
|
|
151
|
-
`),2}}if(import.meta.main)
|
|
133
|
+
`),t===void 0?2:0;default:return process.stderr.write(`Unknown subcommand "${t}". Run "ostia --help".
|
|
134
|
+
`),2}}if(import.meta.main)he().then((t)=>process.exit(t));
|
package/index.js
CHANGED
|
@@ -1,19 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
`}async function Le(e,s){await Bun.write(s,q(e))}async function G(e){let s=await Bun.file(e).text();return JSON.parse(s)}async function Y(e){let s=Bun.nanoseconds(),n=Bun.spawn(e.argv,{cwd:e.cwd,env:e.env,stdout:"ignore",stderr:"ignore",stdin:"ignore"}),r=await n.exited,t=Bun.nanoseconds(),a=n.resourceUsage?.();return{wallNs:t-s,exitCode:r,userNs:a?Number(a.cpuTime.user)*1000:void 0,systemNs:a?Number(a.cpuTime.system)*1000:void 0,maxRssBytes:a?.maxRSS}}function le(e){return e.trim().split(/\s+/).filter(Boolean)}function me(e){if(e.length===0)throw Error("computeTimingStats: samples must be non-empty");let s=e.length,n=de(e),r=0;for(let h=0;h<s;h++)r+=e[h];let t=r/s,a=O(n,0.5),i=0;for(let h=0;h<s;h++){let p=e[h]-t;i+=p*p}let o=Math.sqrt(i/s),c=n[0],m=n[s-1],l=O(n,0.25),d=O(n,0.75),g=d-l,x=l-1.5*g,R=d+1.5*g,y=l-3*g,b=d+3*g,T=0,P=0;for(let h=0;h<s;h++){let p=e[h];if(p<y||p>b)P++;else if(p<x||p>R)T++}return{unit:"ns",samples:e,mean:t,median:a,stddev:o,min:c,max:m,outliers:{mild:T,severe:P}}}function de(e){let s=new Float64Array(e.length);return s.set(e),s.sort(),s}function O(e,s){let n=e.length;if(n===1)return e[0];let r=s*(n-1),t=Math.floor(r),a=Math.ceil(r);if(t===a)return e[t];let i=r-t;return e[t]*(1-i)+e[a]*i}var He=5000000,Je=200;function fe(e,s,n="subprocess"){let r=[],t=e.samples[0];if(t!==void 0){let i=de(e.samples),o=O(i,0.25),m=O(i,0.75)-o;if(t>e.median+3*m&&m>0)r.push({code:"slow-first-run",message:`First run took ${(t/1e6).toFixed(2)}ms, much slower than the median ${(e.median/1e6).toFixed(2)}ms. Consider more warmup.`,data:{firstNs:t,medianNs:e.median}})}if(e.outliers.mild+e.outliers.severe>0)r.push({code:"outliers-detected",message:`${e.outliers.mild+e.outliers.severe} outlier(s) detected (${e.outliers.severe} severe, ${e.outliers.mild} mild).`,data:e.outliers});if(n==="subprocess"&&e.median<He)r.push({code:"fast-command",message:`Median run time (${(e.median/1e6).toFixed(3)}ms) is very fast; results may be dominated by spawn overhead.`,data:{medianNs:e.median}});if(n==="inprocess"&&e.median<Je)r.push({code:"below-timer-resolution",message:`Median run time (${e.median.toFixed(0)}ns) is close to timer resolution; consider a larger batch size or a coarser operation.`,data:{medianNs:e.median}});let a=s.filter((i)=>i!==void 0&&i!==0);if(a.length>0)r.push({code:"nonzero-exit",message:`${a.length} of ${s.length} trial(s) exited non-zero.`,data:{exitCodes:a}});return r}var ze=10,Ve=3000000000,Ke=3;async function ge(e){let s=e.warmup??Ke;for(let l=0;l<s;l++)await Y(e);let n=[],r=e.runs??e.minRuns??ze,t=e.runs!==void 0?0:e.minTotalNs??Ve,a=0,i=0;while(i<r||a<t){let l=await Y(e);if(n.push({i,wallNs:l.wallNs,exitCode:l.exitCode,userNs:l.userNs,systemNs:l.systemNs,maxRssBytes:l.maxRssBytes}),a+=l.wallNs,i++,e.runs!==void 0&&i>=e.runs)break}let o=n.map((l)=>l.wallNs),c=me(o),m=fe(c,n.map((l)=>l.exitCode));return{trials:n,timing:c,warnings:m}}var qe=new URL("./runner.ts",import.meta.url).pathname,Ge=".ostia";async function Ye(e){let n=`${e.outDir??Ge}/bench-tmp`,r=e.cwd??process.cwd(),t={timeBudgetMs:e.timeBudgetMs,minSamples:e.minSamples,gc:e.gc},a=[],i=[];try{for(let o of e.suites){let c=o.startsWith("/")?o:`${r}/${o}`,m=`${n}/${C("bench-out",c)}.json`,d=await Bun.spawn(["bun",qe,c,m,JSON.stringify(t)],{cwd:r,stdout:"inherit",stderr:"inherit",stdin:"ignore"}).exited;if(d!==0)throw Error(`Bench suite failed: ${o} (runner exited ${d})`);let g=await G(m);a.push(...g.workloads),i.push(...g.runs)}}finally{await Bun.spawn(["rm","-rf",n]).exited}return j(a,i)}var Ze=[],H;function Qe(e,s){let n=H;H=e;try{s()}finally{H=n}}function Xe(e,s){Ze.push({groupName:H,name:e,fn:s})}var he={timingPct:5,frameSelfPct:10,heapTypePct:10,minFrameSelfUs:1000};function J(e,s){if(e===0)return s===0?0:1/0;return(s-e)/e*100}function M(e,s,n){return e.runs.find((r)=>r.workloadId===s&&r.phase===n)}function en(e,s,n=he){let r=new Set(s.workloads.map((a)=>a.id)),t=[];for(let a of e.workloads){if(!r.has(a.id))continue;let i=nn(e,s,a.id,n);if(i)t.push(i)}return t}function nn(e,s,n,r=he){let t=M(e,n,"timing"),a=M(s,n,"timing"),i=M(e,n,"cpu"),o=M(s,n,"cpu"),c=M(e,n,"heap"),m=M(s,n,"heap"),l=t?.id??i?.id??c?.id,d=a?.id??o?.id??m?.id;if(!l||!d)return;let g=!1,x;if(t?.timing&&a?.timing){let b=J(t.timing.median,a.timing.median),T=J(t.timing.mean,a.timing.mean),P=b>r.timingPct?"regressed":b<-r.timingPct?"improved":"unchanged";if(P==="regressed")g=!0;x={medianDeltaPct:b,meanDeltaPct:T,verdict:P}}let R;if(i?.cpu&&o?.cpu){let b=new Map(i.cpu.totals.map((f)=>[i.cpu.frames[f.frameIx].key,f])),T=new Map(o.cpu.totals.map((f)=>[o.cpu.frames[f.frameIx].key,f])),P=new Map(i.cpu.frames.map((f)=>[f.key,f.name])),h=new Map(o.cpu.frames.map((f)=>[f.key,f.name]));R=[...new Set([...b.keys(),...T.keys()])].map((f)=>{let u=b.get(f)?.selfUs??0,w=T.get(f)?.selfUs??0;return{frameKey:f,name:h.get(f)??P.get(f)??f,baseSelfUs:u,candSelfUs:w,deltaPct:J(u,w)}}).sort((f,u)=>Math.abs(u.deltaPct)-Math.abs(f.deltaPct));for(let f of R)if((f.baseSelfUs>=r.minFrameSelfUs||f.candSelfUs>=r.minFrameSelfUs)&&f.deltaPct>r.frameSelfPct)g=!0}let y;if(c?.heap&&m?.heap){let b=new Map(c.heap.typeCounts.map((h)=>[h.type,h])),T=new Map(m.heap.typeCounts.map((h)=>[h.type,h]));y=[...new Set([...b.keys(),...T.keys()])].map((h)=>{let p=b.get(h),f=T.get(h);return{type:h,baseCount:p?.count??0,candCount:f?.count??0,baseBytes:p?.retainedBytes,candBytes:f?.retainedBytes,deltaPct:J(p?.count??0,f?.count??0)}}).sort((h,p)=>Math.abs(p.deltaPct)-Math.abs(h.deltaPct));for(let h of y)if(h.deltaPct>r.heapTypePct)g=!0}return{id:C("cmp",l,d),baselineRunId:l,candidateRunId:d,timing:x,frames:R,heapTypes:y,thresholds:r,verdict:g?"fail":"pass"}}function F(e,s){if(s){let n=e.runs.find((r)=>r.id===s);return n?.cpu?[n]:[]}return e.runs.filter((n)=>n.phase==="cpu"&&n.cpu)}function B(e){let s=e.nodes,n=s.length,r=tn(e),t=new Int32Array(n).fill(-1);for(let c=0;c<n;c++)for(let m of s[c].children){let l=r(m);if(l!==-1)t[l]=c}let a=[];for(let c=0;c<n;c++)if(t[c]===-1)a.push(c);let i=[],o=[];for(let c=a.length-1;c>=0;c--)o.push(a[c]);while(o.length>0){let c=o.pop();i.push(c);for(let m of s[c].children){let l=r(m);if(l!==-1&&t[l]===c)o.push(l)}}return{count:n,indexOf:r,parentIx:t,roots:a,order:i}}function tn(e){let s=e.nodes,n=s.length,r=1/0,t=-1/0,a=!0;for(let o=0;o<n;o++){let c=s[o].id;if(!Number.isInteger(c)){a=!1;break}if(c<r)r=c;if(c>t)t=c}if(a&&n>0&&t-r<n*4+64){let o=t-r+1,c=new Int32Array(o).fill(-1);for(let m=0;m<n;m++)c[s[m].id-r]=m;return(m)=>{let l=m-r;return l>=0&&l<o?c[l]:-1}}let i=new Map;for(let o=0;o<n;o++)i.set(s[o].id,o);return(o)=>i.get(o)??-1}function ye(e,s){let{count:n,indexOf:r,parentIx:t,order:a}=s,i=new Float64Array(n),o=new Float64Array(n),c=e.samples?.nodeIds??[],m=e.samples?.timeDeltasUs??[];for(let d=0;d<c.length;d++){let g=r(c[d]);if(g===-1)continue;i[g]+=m[d]??0,o[g]+=1}let l=new Float64Array(n);for(let d=a.length-1;d>=0;d--){let g=a[d];l[g]+=i[g];let x=t[g];if(x>=0)l[x]+=l[g]}return{selfUs:i,totalUs:l,samples:o}}var we={name:"collapsed",async render(e,s={}){return{files:F(e,s.runId).map((t)=>{let a=t.cpu,{nodes:i,frames:o}=a,c=B(a),m=Array(c.count);for(let R of c.order){let y=o[i[R].frameIx].name||"(anonymous)",b=c.parentIx[R];m[R]=b===-1?y:`${m[b]};${y}`}let l=new Float64Array(c.count),d=[],g=a.samples?.nodeIds??[];for(let R=0;R<g.length;R++){let y=c.indexOf(g[R]);if(y===-1)continue;if(l[y]++===0)d.push(y)}let x=Array(d.length);for(let R=0;R<d.length;R++){let y=d[R];x[R]=`${m[y]} ${l[y]}`}return{path:`${t.id}.collapsed.txt`,content:x.join(`
|
|
4
|
-
`)+(x.length>0?`
|
|
5
|
-
`:"")}})}}};var be={name:"cpuprofile",async render(e,s={}){let n=F(e,s.runId),r=[],t=[];for(let a of n){if(a.cpu?.origin!=="cpu-prof"&&a.cpu?.origin!=="inspector"){t.push(`${a.id} (origin ${a.cpu?.origin??"unknown"} has no .cpuprofile artifact to pass through)`);continue}let i=a.artifacts.find((c)=>c.kind==="cpuprofile");if(!i){t.push(`${a.id} (no cpuprofile artifact recorded on this run)`);continue}let o=Bun.file(i.path);if(!await o.exists()){t.push(`${a.id} (artifact missing on disk: ${i.path})`);continue}r.push({path:`${a.id}.cpuprofile`,content:await o.text()})}if(r.length===0&&t.length>0)return{text:`No .cpuprofile artifacts available:
|
|
6
|
-
${t.map((a)=>` - ${a}`).join(`
|
|
7
|
-
`)}
|
|
8
|
-
`};return{files:r}}};var xe={name:"json",async render(e){return{text:q(e)}}};var Re={name:"jsonl",async render(e){let{runs:s,...n}=e;return{text:`${[A(n),...s.map((t)=>A(t))].join(`
|
|
9
|
-
`)}
|
|
10
|
-
`}}};function D(e){return(e/1e6).toFixed(3)}function z(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??e?.id??"unknown"}var Te=10,Pe=10,ke={name:"markdown",async render(e){let s=new Map(e.workloads.map((t)=>[t.id,t])),n=[];n.push("# Profile Report",""),n.push(`Bun ${e.bunVersion} \xB7 ostia ${e.toolVersion} \xB7 ${e.platform.os}/${e.platform.arch} \xB7 ${e.createdAt}`,"");let r=e.runs.filter((t)=>t.phase==="timing"&&t.timing!==void 0);if(r.length>0){n.push("## Timing",""),n.push("| Command | Mean \xB1 SD (ms) | Min\u2026Max (ms) | Median (ms) |","|---|---|---|---|");for(let a of r){let i=z(s.get(a.workloadId)),o=a.timing;n.push(`| ${i} | ${D(o.mean)} \xB1 ${D(o.stddev)} | ${D(o.min)}\u2026${D(o.max)} | ${D(o.median)} |`)}n.push("");let t=r.filter((a)=>a.warnings.length>0);if(t.length>0){n.push("### Warnings","");for(let a of t){let i=z(s.get(a.workloadId));for(let o of a.warnings)n.push(`- **${i}**: ${o.message} (\`${o.code}\`)`)}n.push("")}}for(let t of e.runs){if(t.phase!=="cpu"&&t.phase!=="heap")continue;let a=z(s.get(t.workloadId));if(t.phase==="cpu"){if(n.push(`## CPU capture - ${a}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.cpu){n.push(`origin: \`${t.cpu.origin}\`, interval: ${t.cpu.samplingIntervalUs}\xB5s`,""),n.push("| Self % | Self (ms) | Total (ms) | Frame |","|---|---|---|---|");let i=t.cpu.totals.reduce((o,c)=>o+c.selfUs,0)||1;for(let o of t.cpu.totals.slice(0,Te)){let c=t.cpu.frames[o.frameIx],m=(o.selfUs/i*100).toFixed(1);n.push(`| ${m}% | ${(o.selfUs/1000).toFixed(2)} | ${(o.totalUs/1000).toFixed(2)} | ${c?.name||"(anonymous)"} |`)}if(n.push(""),t.jit){let o=t.jit.tiers;n.push(`JIT tiers: LLInt ${o.llint} \xB7 Baseline ${o.baseline} \xB7 DFG ${o.dfg} \xB7 FTL ${o.ftl}`,"")}}}else if(n.push(`## Heap snapshot - ${a}`,""),n.push(`instrumented, diagnostic wall ${D(t.diagnosticWallNs??0)}ms`,""),t.heap){n.push(`${t.heap.objectCount??"?"} objects, ${((t.heap.heapSizeBytes??0)/1e6).toFixed(2)}MB`,""),n.push("| Count | Type |","|---|---|");for(let i of t.heap.typeCounts.slice(0,Pe))n.push(`| ${i.count} | ${i.type} |`);n.push("")}for(let i of t.artifacts)n.push(`- artifact: \`${i.path}\``);for(let i of t.warnings)n.push(`- ! ${i.message} (\`${i.code}\`)`);if(t.artifacts.length>0||t.warnings.length>0)n.push("")}if(e.comparisons&&e.comparisons.length>0){n.push("## Comparisons","");for(let t of e.comparisons){let a=e.runs.find((o)=>o.id===t.candidateRunId),i=z(a?s.get(a.workloadId):void 0);if(n.push(`### ${t.verdict==="pass"?"\u2713":"\u2717"} ${i}`,""),t.timing){let o=t.timing.medianDeltaPct>0?"+":"";n.push(`- timing: ${o}${t.timing.medianDeltaPct.toFixed(1)}% median (**${t.timing.verdict}**)`)}for(let o of t.frames?.slice(0,Te)??[]){if(Math.abs(o.deltaPct)<0.5)continue;let c=o.deltaPct>0?"+":"";n.push(`- frame \`${o.name}\`: ${c}${o.deltaPct.toFixed(1)}% self-time (${(o.baseSelfUs/1000).toFixed(2)}ms \u2192 ${(o.candSelfUs/1000).toFixed(2)}ms)`)}for(let o of t.heapTypes?.slice(0,Pe)??[]){if(Math.abs(o.deltaPct)<0.5)continue;let c=o.deltaPct>0?"+":"";n.push(`- heap \`${o.type}\`: ${c}${o.deltaPct.toFixed(1)}% count (${o.baseCount} \u2192 ${o.candCount})`)}n.push("")}}return{text:n.join(`
|
|
11
|
-
`)}}};var rn=15;function Z(e){return`n${e}`}function sn(e,s,n){return`${(e||"(anonymous)").replace(/"/g,"'")} (self ${(s/1000).toFixed(2)}ms, total ${(n/1000).toFixed(2)}ms)`}function on(e,s,n,r){let t=[];if(r<=0)return t;for(let a=0;a<s;a++){if(a===n)continue;let i=e[a];if(t.length===r&&i<=e[t[r-1]])continue;let o=t.length;while(o>0&&e[t[o-1]]<i)o--;if(t.splice(o,0,a),t.length>r)t.pop()}return t}var $e={name:"mermaid",async render(e,s={}){let n=s.topN??rn;return{files:F(e,s.runId).map((a)=>{let i=a.cpu,{nodes:o,frames:c}=i,m=B(i),{selfUs:l,totalUs:d}=ye(i,m),{parentIx:g}=m,x=m.roots[0]??-1,R=on(l,m.count,x,n),y=new Set(x!==-1?[x]:[]),b=[];for(let P of R){b.length=0;for(let h=P;h!==-1;h=g[h])b.push(h);for(let h=b.length-1;h>=0;h--)y.add(b[h])}let T=["graph TD"];for(let P of y){let h=o[P].id;T.push(` ${Z(h)}["${sn(c[o[P].frameIx].name,l[P],d[P])}"]`)}for(let P of y){let h=g[P];if(h!==-1&&y.has(h))T.push(` ${Z(o[h].id)} --> ${Z(o[P].id)}`)}return{path:`${a.id}.mermaid.md`,content:`${T.join(`
|
|
12
|
-
`)}
|
|
13
|
-
`}})}}};var an="https://www.speedscope.app/file-format-schema.json";function Ne(e){return e?.label??e?.command?.join(" ")??e?.entry?.task??"profile"}var Ce={name:"speedscope",async render(e,s={}){let n=F(e,s.runId),r=new Map(e.workloads.map((a)=>[a.id,a]));return{files:n.map((a)=>{let i=a.cpu,{nodes:o}=i,c=B(i),m=i.samples?.nodeIds??[],l=i.samples?.timeDeltasUs??[],d=Array(c.count);for(let y of c.order){let b=c.parentIx[y],T=o[y].frameIx;d[y]=b===-1?[T]:[...d[b],T]}let g=Array(m.length);for(let y=0;y<m.length;y++){let b=c.indexOf(m[y]);g[y]=b===-1?[]:d[b]}let x=0;for(let y=0;y<l.length;y++)x+=l[y];let R={$schema:an,exporter:"ostia",name:Ne(r.get(a.workloadId)),activeProfileIndex:0,shared:{frames:i.frames.map((y)=>({name:y.name||"(anonymous)",file:y.url,line:y.line!==void 0?y.line+1:void 0}))},profiles:[{type:"sampled",name:Ne(r.get(a.workloadId)),unit:"microseconds",startValue:0,endValue:x,samples:g,weights:l}]};return{path:`${a.id}.speedscope.json`,content:`${JSON.stringify(R,null,2)}
|
|
14
|
-
`}})}}};function E(e){return(e/1e6).toFixed(3)}function Q(e){return e.label??e.command?.join(" ")??e.entry?.task??e.id}var Ie={name:"table",async render(e){let s=e.runs.filter((d)=>d.phase==="timing"&&d.timing!==void 0),n=new Map(e.workloads.map((d)=>[d.id,d]));if(s.length===0){let d=ve(e,n);return{text:d.length>0?`${d.join(`
|
|
15
|
-
`)}
|
|
16
|
-
`:`(no timing runs)
|
|
17
|
-
`}}let r=s.map((d)=>{let g=n.get(d.workloadId);return{run:d,workload:g,label:g?Q(g):d.workloadId}}),t=Math.min(...r.map((d)=>d.run.timing.median)),a=r.length>1,i=[],o=Math.max(7,...r.map((d)=>d.label.length)),c=a?`${"Command".padEnd(o)} Mean [ms] Min\u2026Max [ms] Relative`:`${"Command".padEnd(o)} Mean [ms] Min\u2026Max [ms]`;i.push(c),i.push("-".repeat(c.length));for(let{run:d,label:g}of r){let x=d.timing,R=`${E(x.mean)} \xB1 ${E(x.stddev)}`,y=`${E(x.min)}\u2026${E(x.max)}`,b=`${g.padEnd(o)} ${R.padEnd(15)} ${y.padEnd(18)}`;if(a){let T=x.median/t;b+=T===1?" 1.00\xD7":` ${T.toFixed(2)}\xD7 slower`}i.push(b);for(let T of d.warnings)i.push(` ! ${T.message}`)}let m=un(e,n);if(m.length>0)i.push(""),i.push(...m);let l=ve(e,n);if(l.length>0)i.push(""),i.push(...l);return{text:`${i.join(`
|
|
18
|
-
`)}
|
|
19
|
-
`}}};function cn(e,s,n){let r=e.runs.find((a)=>a.id===n),t=r?s.get(r.workloadId):void 0;return t?Q(t):n}function ve(e,s){if(!e.comparisons||e.comparisons.length===0)return[];let n=[];for(let r of e.comparisons){let t=cn(e,s,r.candidateRunId),a=r.verdict==="pass"?"\u2713":"\u2717";if(n.push(`${a} ${t}`),r.timing){let i=r.timing.medianDeltaPct>0?"+":"";n.push(` timing: ${i}${r.timing.medianDeltaPct.toFixed(1)}% median (${r.timing.verdict})`)}if(r.frames)for(let i of r.frames.slice(0,Ue)){if(Math.abs(i.deltaPct)<0.5)continue;let o=i.deltaPct>0?"+":"";n.push(` frame ${i.name}: ${o}${i.deltaPct.toFixed(1)}% self-time (${(i.baseSelfUs/1000).toFixed(2)}ms -> ${(i.candSelfUs/1000).toFixed(2)}ms)`)}if(r.heapTypes)for(let i of r.heapTypes.slice(0,Fe)){if(Math.abs(i.deltaPct)<0.5)continue;let o=i.deltaPct>0?"+":"";n.push(` heap ${i.type}: ${o}${i.deltaPct.toFixed(1)}% count (${i.baseCount} -> ${i.candCount})`)}}return n}var Ue=5,Fe=5;function un(e,s){let n=[];for(let r of e.runs){if(r.phase!=="cpu"&&r.phase!=="heap")continue;let t=s.get(r.workloadId),a=t?Q(t):r.workloadId;if(r.phase==="cpu")if(r.cpu){n.push(`CPU capture - ${a} (instrumented, ${r.cpu.samplingIntervalUs}\xB5s interval, diagnostic wall ${E(r.diagnosticWallNs??0)}ms)`);let i=r.cpu.totals.reduce((o,c)=>o+c.selfUs,0)||1;for(let o of r.cpu.totals.slice(0,Ue)){let c=r.cpu.frames[o.frameIx],m=(o.selfUs/i*100).toFixed(1);n.push(` ${m.padStart(5)}% ${(o.selfUs/1000).toFixed(2).padStart(8)}ms self ${c?.name??"?"}`)}}else n.push(`CPU capture - ${a} (instrumented, no evidence captured)`);else if(r.heap){let i=((r.heap.heapSizeBytes??0)/1e6).toFixed(2);n.push(`Heap snapshot - ${a} (instrumented, ${r.heap.objectCount??"?"} objects, ${i}MB)`);for(let o of r.heap.typeCounts.slice(0,Fe))n.push(` ${String(o.count).padStart(6)} ${o.type}`)}else n.push(`Heap snapshot - ${a} (instrumented, no evidence captured)`);for(let i of r.artifacts)n.push(` artifact: ${i.path}`);for(let i of r.warnings)n.push(` ! ${i.message}`)}return n}var pn={table:Ie,json:xe,markdown:ke,jsonl:Re,collapsed:we,mermaid:$e,speedscope:Ce,cpuprofile:be};var ln=".ostia",X=1000;async function wt(e){let s=K({runs:e.runs??null,warmup:e.warmup??null,cpu:e.cpu??!1,heap:e.heap??!1,cpuIntervalUs:e.cpuIntervalUs??X}),r=`${e.outDir??ln}/artifacts`,t=[],a=[];for(let i of e.commands){let o=Array.isArray(i)?i:le(i),c=ae(o,Array.isArray(i)?void 0:i);t.push(c);let m=await ge({argv:o,cwd:e.cwd,env:e.env,runs:e.runs,warmup:e.warmup}),l=ue({workload:c,configFingerprint:s,trials:m.trials,timing:m.timing,warnings:m.warnings});if(a.push(l),e.cpu){let d=`${l.id}-cpu.cpuprofile`,g=await ee({argv:o,cwd:e.cwd,env:e.env,artifactDir:r,fileName:d,intervalUs:e.cpuIntervalUs??X});a.push(await De({workload:c,phase:"cpu",configFingerprint:s,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,cpu:g.cpu,artifactPath:g.artifactPath,artifactKind:"cpuprofile",warnings:g.warnings}))}if(e.heap){let d=`${l.id}-heap.heapsnapshot`,g=await te({argv:o,cwd:e.cwd,env:e.env,artifactDir:r,fileName:d});a.push(await De({workload:c,phase:"heap",configFingerprint:s,diagnosticWallNs:g.diagnosticWallNs,exitCode:g.exitCode,heap:g.heap,artifactPath:g.artifactPath,artifactKind:"heapsnapshot",warnings:g.warnings}))}}return j(t,a)}async function De(e){let s=`${e.workload.id}-${e.phase}-${e.configFingerprint}`,n=e.artifactPath?[await pe(s,e.artifactKind,e.artifactPath)]:[];return L({workload:e.workload,phase:e.phase,configFingerprint:e.configFingerprint,diagnosticWallNs:e.diagnosticWallNs,exitCode:e.exitCode,cpu:e.cpu,heap:e.heap,warnings:e.warnings,artifacts:n})}async function bt(e,s={}){let n=ce(e),r=K({intervalUs:s.intervalUs??X,origin:s.origin??"inspector"}),t=(m)=>m.samples?.nodeIds.length===0?[{code:"empty-profile",message:"In-process capture produced zero samples."}]:[];if(s.origin==="jsc"){let{result:m,cpu:l,jit:d,diagnosticWallNs:g}=await ie(e,s),x=L({workload:n,phase:"cpu",configFingerprint:r,diagnosticWallNs:g,cpu:l,jit:d,warnings:t(l),artifacts:[]});return{result:m,run:x}}let{result:a,cpu:i,diagnosticWallNs:o}=await re(e,s),c=L({workload:n,phase:"cpu",configFingerprint:r,diagnosticWallNs:o,cpu:i,warnings:t(i),artifacts:[]});return{result:a,run:c}}export{Ye as bench,en as compareDocuments,Qe as group,G as loadDocument,bt as profile,pn as renderers,wt as run,Le as saveDocument,Xe as task};
|
|
2
|
+
import{a as c,c as d,f as g,g as h,h as i}from"./chunk-j0j2b0fj.js";import{u as a,v as b,y as e,z as f}from"./chunk-ck12vbed.js";export{c as bench,d as compareDocuments,e as group,b as loadDocument,i as profile,g as renderers,h as run,a as saveDocument,f as task};
|
package/package.json
CHANGED
package/runner.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
import{A as P,B as E,l as M,o as F,p as N,s as y,u as I,w as B,x as h}from"./chunk-ck12vbed.js";var A=500,D=20,O=0.1,k=1000,S=0;function d(n){if(typeof n==="number")S+=n;else if(n!==void 0&&n!==null)S+=1}function x(n){return n!==null&&typeof n==="object"&&typeof n.then==="function"}async function b(n,t={}){let r=(t.timeBudgetMs??A)*1e6,e=t.minSamples??D,c=r*(t.warmupFraction??O),p=Bun.nanoseconds();while(Bun.nanoseconds()-p<c)d(await n());let m=Bun.nanoseconds();d(await n());let a=Math.max(1,Bun.nanoseconds()-m),s=a<k?Math.max(1,Math.ceil(k/a)):1,i=[],u=Bun.nanoseconds(),o=0,l=0;while(l<e||o<r){let g=Bun.nanoseconds();for(let T=0;T<s;T++){let w=n();d(x(w)?await w:w)}let R=Bun.nanoseconds();if(i.push({i:l,wallNs:(R-g)/s}),l++,o=Bun.nanoseconds()-u,t.gc)Bun.gc(!0)}let _=i.map((g)=>g.wallNs),f=B(_),L=h(f,[],"inprocess");return{trials:i,timing:f,warnings:L}}async function U(){let[n,t,r]=process.argv.slice(2);if(!n||!t)return process.stderr.write(`bench runner: usage: runner.ts <suiteFile> <outputPath> [optsJson]
|
|
4
|
+
`),2;let e=r?JSON.parse(r):{};E(),await import(n);let c=P();if(c.length===0)return process.stderr.write(`bench runner: ${n} registered no tasks (no task() calls found).
|
|
5
|
+
`),2;let p=y({timeBudgetMs:e.timeBudgetMs??null,minSamples:e.minSamples??null,gc:e.gc??!1}),m=[],a=[];for(let s of c){let i=s.groupName?`${s.groupName}/${s.name}`:s.name,u=F(n,i,i);m.push(u);let o=await b(s.fn,e);a.push(N({workload:u,configFingerprint:p,trials:o.trials,timing:o.timing,warnings:o.warnings}))}return await I(M(m,a),t),0}U().then((n)=>process.exit(n));
|