Files
anonymous_github/backend/scripts/render-slower-path-optimization.cjs
T

24 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs=require('fs'),assert=require('assert/strict');
const before=JSON.parse(fs.readFileSync('backend/reports/repository-runtime-comparison.json'));
const after=JSON.parse(fs.readFileSync('backend/reports/repository-runtime-comparison-after.json'));
const median=a=>{a=[...a].sort((a,b)=>a-b);return (a[Math.floor((a.length-1)/2)]+a[Math.floor(a.length/2)])/2};
const summary=after.results[0].results.map(x=>{
const row={name:x.name};
for(const [label,report,runtime] of [['ts',after,'node'],['goBefore',before,'go'],['goAfter',after,'go']]){
const runs=report.results.filter(x=>x.runtime===runtime).map(run=>run.results.find(y=>y.name===row.name));
assert(runs.every(x=>x.output.status===200));
row[label]={output:runs[0].output,coldMs:median(runs.map(x=>x.cold.ms)),warm:Object.fromEntries([1,8].map(c=>[c,Object.fromEntries(['p50Ms','p95Ms','cpuMs','peakProcessTreeRssBytes','requestsPerSecond'].map(m=>[m,median(runs.map(x=>x.warm.find(w=>w.concurrency===c)[m]))]))]))};
}
assert.deepEqual(row.ts.output,row.goBefore.output);assert.deepEqual(row.ts.output,row.goAfter.output);
return row;
});
const report={fixture:after.fixture,method:after.method,validation:{outputs:'All seven response signatures match TypeScript, Go before and Go after in both rounds.',tests:['Targeted race suites passed: large tree scans, index parity/eviction/collisions, website lookup, shared HTTP authorization and representations.','go vet passed.']},summary};
fs.writeFileSync('backend/reports/slower-path-optimization.json',JSON.stringify(report,null,2));
const html=`<!doctype html><html><head><meta charset="utf-8"><style>
body{font-family:var(--font-sans,system-ui);color:var(--foreground,#222);margin:0;line-height:1.5}h2{font-size:22px;margin:0 0 8px}p{color:var(--muted-foreground,#666);margin:10px 0;font-size:14px}select{font:inherit;background:var(--background,white);color:inherit;border:1px solid var(--border,#ddd);border-radius:6px;padding:7px}table{border-collapse:collapse;width:100%;margin:16px 0;font-size:14px}th,td{padding:12px 6px;border-bottom:1px solid var(--border,#ddd);text-align:right;font-variant-numeric:tabular-nums}th:first-child,td:first-child{text-align:left;padding-left:0}th{font-size:12px;color:var(--muted-foreground,#666)}.after{color:var(--success,#24724b);font-weight:600}details{margin-top:14px;font-size:13px}.scroll{overflow:auto}label{font-size:13px}#note{font-size:13px}
</style></head><body><h2>Go’s slower paths, corrected</h2><p>Same repository snapshot and 1,000-file directory fixture. Both runtimes rerun in alternating order; all seven successful response signatures still match.</p><label>Measure <select id="mode"><option value="1">Warm median, sequential requests</option><option value="8">Warm median, eight concurrent requests</option><option value="cold">First request</option></select></label><div class="scroll"><table><thead><tr><th>Use case</th><th>TypeScript</th><th>Go before</th><th>Go after</th></tr></thead><tbody id="rows"></tbody></table></div><p id="note"></p><details><summary>Other measured endpoints</summary><div class="scroll"><table><thead><tr><th>Use case</th><th>TypeScript</th><th>Go before</th><th>Go after</th></tr></thead><tbody id="other"></tbody></table></div></details><p>Counts now aggregate by directory in MongoDB. Website files use verified direct lookups or a collision-aware path index, with live snapshot and authorization checks.</p><p style="font-size:12px">Loopback backend timings, identity encoding, shared caches enabled, one worker. Two rounds; medians of per-round medians. Excludes GitHub, CDN and browser rendering. First masked/custom-path requests can still build an index. ZIP was not rerun because these changes do not alter its serving path.</p><script>
const rows=${JSON.stringify(summary)};function draw(){const mode=document.getElementById('mode').value;document.getElementById('rows').replaceChildren();document.getElementById('other').replaceChildren();for(const row of rows){const tr=document.createElement('tr');const name=document.createElement('td');name.textContent=row.name==='website gulpfile.js'?'/w/ file':row.name;tr.append(name);for(const key of ['ts','goBefore','goAfter']){const td=document.createElement('td');td.textContent=(mode==='cold'?row[key].coldMs:row[key].warm[mode].p50Ms).toFixed(1)+' ms';if(key==='goAfter')td.className='after';tr.append(td)}document.getElementById(['file counts','website gulpfile.js'].includes(row.name)?'rows':'other').append(tr)}document.getElementById('note').textContent=mode==='cold'?'First requests can share dependencies warmed by earlier endpoints; filesystem caches were not cleared.':'Warm measurements use 32 requests per endpoint and concurrency level in each round.';}document.getElementById('mode').onchange=draw;draw();
</script></body></html>`;
fs.writeFileSync('backend/reports/slower-path-optimization.html',html);
console.log(JSON.stringify(summary.filter(x=>['file counts','website gulpfile.js'].includes(x.name)),null,2));