/* eslint-disable no-console */ import { readFile } from 'fs/promises'; import { globby } from 'globby'; import { markdownTable } from 'markdown-table'; interface RunTimes { [key: string]: number; } interface TestResult { [key: string]: RunTimes; } const getRuntimes = (csv: string): RunTimes => { const lines = csv.split('\n'); const runtimes: RunTimes = {}; for (const line of lines) { const [testName, timeTaken] = line.split(','); if (testName && timeTaken) { runtimes[testName] = Number(timeTaken); // TODO: Add some variation to test logging. Should remove. if (Math.random() < 0.3) { runtimes[testName] *= Math.random() * 2; } } } return runtimes; }; const readStats = async (path: string): Promise => { const files = await globby(path); const contents = await Promise.all( files.map(async (file) => [file, await readFile(file, 'utf-8')]) ); const sizes = contents.map(([file, content]) => [file.split('/').pop(), getRuntimes(content)]); return Object.fromEntries(sizes); }; const percentChangeThreshold = 5; const percentageDifference = ( oldValue: number, newValue: number ): { change: string; crossedThreshold: boolean } => { const difference = Math.abs(newValue - oldValue); const avg = (newValue + oldValue) / 2; const percentage = (difference / avg) * 100; const roundedPercentage = percentage.toFixed(2); // Round to two decimal places if (roundedPercentage === '0.00') { return { change: '0.00%', crossedThreshold: false }; } const sign = newValue > oldValue ? '+' : '-'; return { change: `${sign}${roundedPercentage}%`, crossedThreshold: percentage > percentChangeThreshold, }; }; const main = async () => { const oldStats = await readStats('./snapshots/runtimes/base/**/*.csv'); const newStats = await readStats('./snapshots/runtimes/head/**/*.csv'); const fullData: string[][] = []; const changed: string[][] = []; for (const [fileName, runtimes] of Object.entries(newStats)) { const oldStat = oldStats[fileName]; if (!oldStat) { continue; } for (const [testName, timeTaken] of Object.entries(runtimes)) { const oldTimeTaken = oldStat[testName]; if (!oldTimeTaken) { continue; } const delta = timeTaken - oldTimeTaken; const { change, crossedThreshold } = percentageDifference(oldTimeTaken, timeTaken); const out = [ fileName, testName, oldTimeTaken.toString(), timeTaken.toString(), change, `${delta.toString()}ms`, ]; if (crossedThreshold) { changed.push(out); console.warn(`${testName} (${fileName}): ${timeTaken}ms (${delta}ms, ${change})`); } fullData.push(out); } } const headers = ['File', 'Test', 'Old Time', 'New Time', '% Change', 'Difference']; console.log(markdownTable([headers, ...changed])); console.log(`
Full Data ${markdownTable([headers, ...fullData])}
`); }; void main().catch((e) => console.error(e));