Files
FreeCADWasmDev/tools/report_ifc_performance.mjs

52 lines
4.1 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
const directory=path.join(root,'docs/current/user-tests-20260915');
const baseline='manual-2026-09-15T16-41-07-796Z';
const original=JSON.parse(fs.readFileSync(path.join(directory,baseline,'results.json'))).results
.find(c=>c.id==='FILE-02').steps.find(s=>s.name.startsWith('IFC '));
const events=fs.readFileSync(path.join(directory,baseline,'events.ndjson'),'utf8').trim().split('\n')
.map(JSON.parse).filter(e=>e.test==='FILE-02'&&e.params.entry?.text.startsWith('IFC'));
const phases={conversionAndDispatch:0,productProcessing:0,repairAndRevalidation:0,scene:0};
for(let i=1;i<events.length;i++){
const previous=events[i-1],seconds=(Date.parse(events[i].at)-Date.parse(previous.at))/1000;
const name=previous.params.entry.text;
phases[name.startsWith('IFC scene:')?'scene':name.startsWith('IFC: repairing')?'repairAndRevalidation':name.startsWith('IFC: product')?'productProcessing':'conversionAndDispatch']+=seconds;
}
const runs=[];
for(const entry of fs.readdirSync(directory,{withFileTypes:true}).filter(e=>e.isDirectory()&&e.name.startsWith('ifc-native-'))){
const folder=path.join(directory,entry.name),log=path.join(folder,'native.log');
if(!fs.existsSync(log))continue;
const timings=fs.readFileSync(log,'utf8').split('\n').filter(line=>line.startsWith('IFC timing: ')).map(line=>JSON.parse(line.slice(12)));
if(!timings.length)continue;
const result=fs.existsSync(path.join(folder,'results.json'))?JSON.parse(fs.readFileSync(path.join(folder,'results.json'))):[];
const summary=fs.existsSync(path.join(folder,'summary.json'))?JSON.parse(fs.readFileSync(path.join(folder,'summary.json'))):null;
const failure=fs.existsSync(path.join(folder,'failure.json'))?JSON.parse(fs.readFileSync(path.join(folder,'failure.json'))):null;
const experiment=fs.existsSync(path.join(folder,'experiment-status.json'))?JSON.parse(fs.readFileSync(path.join(folder,'experiment-status.json'))):null;
runs.push({run:entry.name,completed:Boolean(summary),status:summary?.status??failure?.status??experiment?.status??'incomplete_or_running',error:failure?.error,
importSeconds:result.find(r=>r.command==='Std_Open')?.seconds,products:timings.length,
productSeconds:timings.reduce((n,r)=>n+r.productSeconds,0),validationSeconds:timings.reduce((n,r)=>n+r.validationSeconds,0),
repairSeconds:timings.reduce((n,r)=>n+r.repairSeconds,0),
slowest:timings.sort((a,b)=>b.productSeconds-a.productSeconds).slice(0,10)});
}
const browserRuns=[];
for(const entry of fs.readdirSync(directory,{withFileTypes:true}).filter(e=>e.isDirectory()&&e.name>baseline&&e.name.startsWith('manual-'))){
const resultFile=path.join(directory,entry.name,'results.json');if(!fs.existsSync(resultFile))continue;
const result=JSON.parse(fs.readFileSync(resultFile)).results.find(c=>c.id==='FILE-02');
const step=result?.steps.find(s=>s.name.startsWith('IFC '));if(!step||step.status!=='passed')continue;
const environment=JSON.parse(fs.readFileSync(path.join(directory,entry.name,'environment.json')));
const formats=JSON.parse(fs.readFileSync(path.join(directory,entry.name,'format-validation.json')));
const ifc=formats.find(f=>f.format==='ifc');
browserRuns.push({run:entry.name,seconds:step.seconds,reductionPercent:(1-step.seconds/original.seconds)*100,
fixtureSha256:ifc?.sha256,browser:environment.browser.product,viewport:environment.viewport,
objects:ifc?.result?.opened?.[0]?.documents?.[0]?.objectCount,meshes:ifc?.result?.scene?.meshes.length,
triangles:ifc?.result?.scene?.meshes.reduce((n,m)=>n+m.triangles.length,0)});
}
const report={baseline:{run:baseline,browserImportSeconds:original.seconds,logIntervalEstimate:phases,
note:'Neighboring browser log intervals, not profiler attribution; native-only times are not directly equivalent to browser wall time.'},runs,browserRuns};
const output=path.join(directory,'ifc-performance-20260916.json');
fs.writeFileSync(output,JSON.stringify(report,null,2)+'\n');
console.log(JSON.stringify({output,baseline:report.baseline,runs:runs.map(({slowest,...r})=>r)},null,2));