mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-11-14 00:07:00 +01:00
9 lines
13 KiB
HTML
9 lines
13 KiB
HTML
<!doctype html><html><head><meta charset="utf-8"><style>
|
||
body{font-family:var(--font-sans,system-ui);color:var(--foreground,#222);line-height:1.5;margin:0}h2{font-size:23px;margin:0 0 8px}p{margin:8px 0 18px;color:var(--muted-foreground,#666)}select{font:inherit;padding:7px;background:var(--background,white);color:inherit;border:1px solid var(--border,#ddd);border-radius:6px}table{border-collapse:collapse;width:100%;font-size:14px;margin:16px 0}th,td{text-align:right;padding:11px 7px;border-bottom:1px solid var(--border,#ddd);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)}small{font-size:12px}.note{font-size:13px}.better{color:var(--success,#23744c)}.worse{color:var(--destructive,#b34242)}details{font-size:13px;margin-top:16px}#scroll{overflow:auto}
|
||
</style></head><body><h2>Go vs TypeScript · same repository snapshot</h2><p>1,017 repository files plus a synthetic 1,000-file directory. Two rounds with runtime order reversed.</p><label>Measurement <select id="mode"><option value="warm1">Warm, one request at a time</option><option value="warm8">Warm, eight concurrent requests</option><option value="p95">Warm p95, eight concurrent requests</option><option value="cold">First request after startup</option><option value="ttfb">Warm time to first body byte</option><option value="cpu">Warm CPU per request</option><option value="rss">Peak process-tree memory</option></select></label><div id="scroll"><table><thead><tr><th>Use case</th><th>TypeScript</th><th>Go</th><th>Go / TS</th></tr></thead><tbody id="rows"></tbody></table></div><p id="caption" class="note"></p><p class="note">Loopback HTTP, identical archive originals, filesystem storage, shared caches enabled, one anonymization worker, identity encoding. No CDN, GitHub round trips or browser rendering. TypeScript ZIP was retested with a temporary admin key and the same source ZIP served over loopback; its worker aborted both attempts. These are backend measurements, not beta page-load times.</p><details><summary>Validation and limits</summary><p id="parity"></p><p>Commit b09ef0e5b0027756ad86eb3353a5ff6416016ade. Node v24.14.1; go version go1.27.3 linux/amd64. Warm results are medians of each round's p50, not pooled percentiles. Each round uses 32 requests per concurrency for normal endpoints and 3 sequential ZIP downloads. First requests can share dependencies warmed by earlier endpoints. RSS includes application workers but excludes MongoDB, Redis and the client. CPU includes background work. RSS includes caches retained from earlier cases. The OS page cache was not dropped. The selected small files contain no occurrence of the configured anonymization term; these timings do not measure replacement-heavy text.</p></details><script>
|
||
const data=[{"name":"root directory","node":{"status":200,"output":{"status":200,"sha256":"52d03ac37d3e22e85d9629413d91a29d1f98410b2d34e419785ba1ad00dafa9d","entries":24},"coldMs":124.26789300002383,"warm":[{"concurrency":1,"p50Ms":27.851555499993992,"p95Ms":40.67887150000388,"firstBodyMs":27.715671000012662,"requestsPerSecond":33.940543569219095,"cpuMsPerRequest":36.71875,"peakRSSMiB":290.81640625},{"concurrency":8,"p50Ms":120.4976090000182,"p95Ms":164.89869749998434,"firstBodyMs":120.43483450001622,"requestsPerSecond":63.59059160386532,"cpuMsPerRequest":23.90625,"peakRSSMiB":296.03125}]},"go":{"status":200,"output":{"status":200,"sha256":"52d03ac37d3e22e85d9629413d91a29d1f98410b2d34e419785ba1ad00dafa9d","entries":24},"coldMs":19.393674499988265,"warm":[{"concurrency":1,"p50Ms":7.403331500001514,"p95Ms":10.997728000002098,"firstBodyMs":7.362432500005525,"requestsPerSecond":123.65028053177949,"cpuMsPerRequest":5.78125,"peakRSSMiB":70.28515625},{"concurrency":8,"p50Ms":9.341673500006436,"p95Ms":22.23802649999925,"firstBodyMs":9.310406999997213,"requestsPerSecond":625.0860770621364,"cpuMsPerRequest":5.625,"peakRSSMiB":77.53125}]},"outputParity":true},{"name":"src directory","node":{"status":200,"output":{"status":200,"sha256":"012081e4d80b7bf24a5931359e89d5fefa0489a7989fd86ff4fdc01bb090d92b","entries":7},"coldMs":29.600288000001456,"warm":[{"concurrency":1,"p50Ms":21.103132500018546,"p95Ms":26.784148500008087,"firstBodyMs":21.013871000019208,"requestsPerSecond":47.07692828634931,"cpuMsPerRequest":17.8125,"peakRSSMiB":297.3203125},{"concurrency":8,"p50Ms":99.87959550002051,"p95Ms":115.40365999999449,"firstBodyMs":99.81212050000431,"requestsPerSecond":78.32172661172507,"cpuMsPerRequest":15.46875,"peakRSSMiB":298.09375}]},"go":{"status":200,"output":{"status":200,"sha256":"012081e4d80b7bf24a5931359e89d5fefa0489a7989fd86ff4fdc01bb090d92b","entries":7},"coldMs":8.060878500000399,"warm":[{"concurrency":1,"p50Ms":6.060465499998827,"p95Ms":7.087685999991663,"firstBodyMs":6.018084999988787,"requestsPerSecond":160.05552208096725,"cpuMsPerRequest":3.59375,"peakRSSMiB":78.49609375},{"concurrency":8,"p50Ms":8.227547999998933,"p95Ms":12.091938999994454,"firstBodyMs":8.07191499998953,"requestsPerSecond":852.6113434439787,"cpuMsPerRequest":3.125,"peakRSSMiB":81.44921875}]},"outputParity":true},{"name":"1000-file directory","node":{"status":200,"output":{"status":200,"sha256":"8b091406715c6232458f52f8c2516031ed2359d2586737cb3923559f96c8c841","entries":1000},"coldMs":111.27095649999137,"warm":[{"concurrency":1,"p50Ms":87.43108849998498,"p95Ms":131.29066700000112,"firstBodyMs":87.0139924999985,"requestsPerSecond":10.69992739910396,"cpuMsPerRequest":97.5,"peakRSSMiB":321.40625},{"concurrency":8,"p50Ms":467.85040200000003,"p95Ms":714.7312750000092,"firstBodyMs":467.5506284999883,"requestsPerSecond":16.24940912171465,"cpuMsPerRequest":68.125,"peakRSSMiB":329.9140625}]},"go":{"status":200,"output":{"status":200,"sha256":"8b091406715c6232458f52f8c2516031ed2359d2586737cb3923559f96c8c841","entries":1000},"coldMs":62.96934049999618,"warm":[{"concurrency":1,"p50Ms":64.99477400000251,"p95Ms":77.43742199999542,"firstBodyMs":64.49705750000066,"requestsPerSecond":15.166581719605437,"cpuMsPerRequest":58.90625,"peakRSSMiB":311.6640625},{"concurrency":8,"p50Ms":53.277233500000875,"p95Ms":77.01955949999683,"firstBodyMs":52.56587999999829,"requestsPerSecond":133.32074875303596,"cpuMsPerRequest":37.5,"peakRSSMiB":330.89453125}]},"outputParity":true},{"name":"file counts","node":{"status":200,"output":{"status":200,"sha256":"14157927c66f50f4a524e003f0dd849218f678cffc266a149d37b2afc6c64386","entries":45},"coldMs":35.10612549999678,"warm":[{"concurrency":1,"p50Ms":27.46849800001837,"p95Ms":36.28570749999744,"firstBodyMs":27.41985600001135,"requestsPerSecond":35.061151545616575,"cpuMsPerRequest":12.03125,"peakRSSMiB":329.9140625},{"concurrency":8,"p50Ms":65.49185800000487,"p95Ms":85.11255699997673,"firstBodyMs":65.4482995000053,"requestsPerSecond":114.07828438374645,"cpuMsPerRequest":10.9375,"peakRSSMiB":330.9453125}]},"go":{"status":200,"output":{"status":200,"sha256":"14157927c66f50f4a524e003f0dd849218f678cffc266a149d37b2afc6c64386","entries":45},"coldMs":69.7607330000028,"warm":[{"concurrency":1,"p50Ms":69.8233264999908,"p95Ms":93.21686600000248,"firstBodyMs":69.77879499999108,"requestsPerSecond":13.910285428547263,"cpuMsPerRequest":59.375,"peakRSSMiB":347.93359375},{"concurrency":8,"p50Ms":78.61524899999495,"p95Ms":90.27311950000148,"firstBodyMs":78.58660099999543,"requestsPerSecond":96.82411463773647,"cpuMsPerRequest":46.25,"peakRSSMiB":350.60546875}]},"outputParity":true},{"name":"gulpfile.js","node":{"status":200,"output":{"status":200,"sha256":"582a19c5d0d13b0526acfa491de26b4ad60f75c7fa13fed1054d7f66d22385fc"},"coldMs":87.3551985000031,"warm":[{"concurrency":1,"p50Ms":24.51233999998476,"p95Ms":34.56796700001178,"firstBodyMs":24.427493499995762,"requestsPerSecond":38.75067075913438,"cpuMsPerRequest":25.46875,"peakRSSMiB":333.53515625},{"concurrency":8,"p50Ms":121.27679049999824,"p95Ms":144.72783400000299,"firstBodyMs":121.12374149998686,"requestsPerSecond":64.61059420825467,"cpuMsPerRequest":22.1875,"peakRSSMiB":334.875}]},"go":{"status":200,"output":{"status":200,"sha256":"582a19c5d0d13b0526acfa491de26b4ad60f75c7fa13fed1054d7f66d22385fc"},"coldMs":61.77973450000354,"warm":[{"concurrency":1,"p50Ms":17.54745600000024,"p95Ms":20.274646999998367,"firstBodyMs":15.356433000000834,"requestsPerSecond":55.82094005020072,"cpuMsPerRequest":11.25,"peakRSSMiB":351.4453125},{"concurrency":8,"p50Ms":68.20507649999126,"p95Ms":81.87241249999352,"firstBodyMs":65.7961060000016,"requestsPerSecond":107.10527593451862,"cpuMsPerRequest":11.09375,"peakRSSMiB":351.97265625}]},"outputParity":true},{"name":"src/config.ts","node":{"status":200,"output":{"status":200,"sha256":"dadc35430eb9fa79ccf887b613704619199cbd111af8dddfc30e5c6ca3f5d003"},"coldMs":22.33179449999261,"warm":[{"concurrency":1,"p50Ms":22.85149049998472,"p95Ms":26.94339250001758,"firstBodyMs":22.569827000008445,"requestsPerSecond":42.240803528256805,"cpuMsPerRequest":20.9375,"peakRSSMiB":337.90234375},{"concurrency":8,"p50Ms":107.67584700000043,"p95Ms":126.13519749999432,"firstBodyMs":107.52199800000744,"requestsPerSecond":70.66061719962136,"cpuMsPerRequest":17.1875,"peakRSSMiB":338.5703125}]},"go":{"status":200,"output":{"status":200,"sha256":"dadc35430eb9fa79ccf887b613704619199cbd111af8dddfc30e5c6ca3f5d003"},"coldMs":58.48024899999291,"warm":[{"concurrency":1,"p50Ms":18.06759750000856,"p95Ms":20.92086200000267,"firstBodyMs":15.731730000003154,"requestsPerSecond":55.03073104274837,"cpuMsPerRequest":11.875,"peakRSSMiB":352.23046875},{"concurrency":8,"p50Ms":60.91620750000584,"p95Ms":67.94174549999661,"firstBodyMs":58.88057199999457,"requestsPerSecond":122.07709644199466,"cpuMsPerRequest":9.375,"peakRSSMiB":352.36328125}]},"outputParity":true},{"name":"website gulpfile.js","node":{"status":200,"output":{"status":200,"sha256":"582a19c5d0d13b0526acfa491de26b4ad60f75c7fa13fed1054d7f66d22385fc"},"coldMs":21.54110999999648,"warm":[{"concurrency":1,"p50Ms":18.027288999994198,"p95Ms":28.667995499989047,"firstBodyMs":17.475921000004746,"requestsPerSecond":51.29987426738056,"cpuMsPerRequest":17.5,"peakRSSMiB":341.28125},{"concurrency":8,"p50Ms":96.45184400001199,"p95Ms":107.52514299999712,"firstBodyMs":96.03611900002761,"requestsPerSecond":81.997789194099,"cpuMsPerRequest":17.34375,"peakRSSMiB":344.38671875}]},"go":{"status":200,"output":{"status":200,"sha256":"582a19c5d0d13b0526acfa491de26b4ad60f75c7fa13fed1054d7f66d22385fc"},"coldMs":77.46532099999968,"warm":[{"concurrency":1,"p50Ms":66.96795449998899,"p95Ms":82.43080350001401,"firstBodyMs":66.29893399999855,"requestsPerSecond":14.836257025333925,"cpuMsPerRequest":52.1875,"peakRSSMiB":356.16015625},{"concurrency":8,"p50Ms":104.15019399999437,"p95Ms":144.24375450000298,"firstBodyMs":103.50109699999666,"requestsPerSecond":68.09919709456383,"cpuMsPerRequest":73.28125,"peakRSSMiB":387.59375}]},"outputParity":true},{"name":"repository ZIP","node":{"status":0,"output":{"status":0,"error":"incomplete response: aborted"},"coldMs":0,"diagnostic":"DataCloneError in TypeScript anonymization worker","warm":[]},"go":{"status":200,"output":{"status":200,"sha256":"72d41a3fe5dcbf91eb33c1682cd4db5ccb220160c35e58e310ead96ac39ac600","entries":2017},"coldMs":40551.099742000006,"warm":[{"concurrency":1,"p50Ms":39991.06115100001,"p95Ms":40371.590815000025,"firstBodyMs":92.73991000000387,"requestsPerSecond":0.025037242385530893,"cpuMsPerRequest":38123.333333333336,"peakRSSMiB":776.31640625}]},"outputParity":false}];
|
||
function render(){const mode=document.getElementById('mode').value;const rows=document.getElementById('rows');rows.replaceChildren();let unit=mode==='rss'?' MiB':' ms';
|
||
function value(r){const w=r.warm.find(x=>x.concurrency===((mode==='warm8'||mode==='p95')?8:1));if(mode==='cold')return r.coldMs;if(!w)return null;return mode==='p95'?w.p95Ms:mode==='ttfb'?w.firstBodyMs:mode==='cpu'?w.cpuMsPerRequest:mode==='rss'?w.peakRSSMiB:w.p50Ms;}
|
||
for(const item of data){const tr=document.createElement('tr'),a=value(item.node),b=value(item.go);const values=[item.name,item.node.status!==200?(item.node.status===0?'Aborted':'HTTP '+item.node.status):a==null?'—':a.toFixed(1)+unit,item.go.status!==200?'HTTP '+item.go.status:b==null?'—':b.toFixed(1)+unit,item.outputParity&&a>0&&b!=null?(b/a).toFixed(2)+'×':'—'];values.forEach((text,i)=>{const td=document.createElement('td');td.textContent=text;if(i===3&&item.outputParity)td.className=b<a?'better':'worse';tr.append(td)});rows.append(tr)}document.getElementById('caption').textContent='Go / TS below 1.00× means Go used less time or memory. Ratios are shown only for matching successful outputs.';document.getElementById('parity').textContent=data.map(x=>x.name+': '+(x.outputParity?'matching output':x.node.diagnostic||'outputs differ or a runtime failed')).join('. ');}
|
||
document.getElementById('mode').onchange=render;render();
|
||
</script></body></html> |