summarize.mjs 1.2 KB

1234567891011
  1. import {readFileSync,writeFileSync} from 'node:fs';
  2. const files=process.argv.slice(2);if(!files.length)throw Error('Pass paired result JSON files');
  3. const rows=files.flatMap(f=>JSON.parse(readFileSync(f,'utf8'))),percentile=(values,p)=>values.toSorted((a,b)=>a-b)[Math.ceil(values.length*p)-1];
  4. const results=[];
  5. for(const operation of new Set(rows.map(r=>r.operation))){
  6. const entry={operation};for(const variant of ['A','B']){const samples=rows.filter(r=>r.operation===operation&&r.variant===variant);if(samples.length!==10)throw Error(operation+' requires exactly 10 samples per variant');
  7. entry[variant]={n:10,p50:percentile(samples.map(r=>r.ms),.5),p75:percentile(samples.map(r=>r.ms),.75),p95:percentile(samples.map(r=>r.ms),.95),requestsPerPage:[...new Set(samples.map(r=>r.requests?.length??1))],bytes:[...new Set(samples.flatMap(r=>r.requests?.map(x=>x.bytes)||[r.bytes]))]};}
  8. for(let pair=0;pair<10;pair++){const a=rows.find(r=>r.operation===operation&&r.variant==='A'&&r.pair===pair),b=rows.find(r=>r.operation===operation&&r.variant==='B'&&r.pair===pair);if(a.hash!==b.hash)throw Error('Golden mismatch '+operation);}
  9. entry.p75ReductionPercent=Math.round((1-entry.B.p75/entry.A.p75)*1000)/10;results.push(entry);
  10. }
  11. console.log(JSON.stringify(results,null,2));