tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

demo-cost.mjs (2572B)


      1 // Opt-in deterministic work/allocation screen, not a wall-time/RAM benchmark.
      2 // Supply an independently retained prior site directory; never rewrite its pins.
      3 import assert from 'node:assert/strict';
      4 import {readFile} from 'node:fs/promises';
      5 import {resolve,join} from 'node:path';
      6 import {fileURLToPath} from 'node:url';
      7 import {createHash} from 'node:crypto';
      8 import {Graph} from '../dist/graph.js';
      9 import {decodeBundle,loadBundle} from '../dist/bundle.js';
     10 import {PACKAGE_BUDGET} from './budgets.mjs';
     11 import {PACKAGE_COLLECTION} from '../dist/execution.js';
     12 // Pure reference execution only; IO goldens run through native browser probes.
     13 const current=fileURLToPath(new URL('../',import.meta.url));
     14 if(!process.argv[2])throw Error('Select the retained reference site directory');
     15 async function measure(directory){
     16   const data=JSON.parse(await readFile(join(directory,'demos.json'))),result={},nativeOnly=[];
     17   for(const [name,demo] of Object.entries(data.demos)){
     18     if(demo.mode==='io'){nativeOnly.push(name);continue;}
     19     const bytes=await readFile(join(directory,'bundles',demo.hash+'.arboricx'));
     20     assert.equal(createHash('sha256').update(bytes).digest('hex'),demo.hash);
     21     const bundle=decodeBundle(bytes);const cases=[];
     22     for(const c of demo.haskellCases){
     23       const g=new Graph(PACKAGE_BUDGET,PACKAGE_COLLECTION),exports=loadBundle(g,bundle);
     24       let output=g.apply(exports.get(c.export),c.arguments.map(tree=>g.fromTernary(tree))),terminal='';
     25       assert.equal(g.toTernary(output),c.result);assert.equal(terminal,c.terminal);
     26       cases.push({key:JSON.stringify([c.export,c.arguments,c.input,c.result,c.terminal]),...g.stats});
     27     }
     28     result[name]={hash:demo.hash,bytes:bytes.length,cases};
     29   }
     30   return {compiler:data.compilerBundleSha256,demos:result,nativeOnly};
     31 }
     32 const before=await measure(resolve(process.argv[2])),after=await measure(current),summary={};
     33 for(const [name,old] of Object.entries(before.demos)){
     34   const next=after.demos[name];assert.ok(next,`missing pure reference demo: ${name}`);let workBefore=0,workAfter=0,allocationsBefore=0,allocationsAfter=0;
     35   for(const c of old.cases){
     36     const n=next.cases.find(n=>n.key===c.key);assert.ok(n,`missing independent reference case: ${name}`);
     37     workBefore+=c.work;workAfter+=n.work;allocationsBefore+=c.allocations;allocationsAfter+=n.allocations;
     38   }
     39   summary[name]={commonCases:old.cases.length,bytesBefore:old.bytes,bytesAfter:next.bytes,
     40     workBefore,workAfter,allocationsBefore,allocationsAfter};
     41 }
     42 console.log(JSON.stringify({summary,before,after},null,2));