This commit is contained in:
seb
2026-10-09 21:37:42 +02:00
parent 00cf5b418e
commit ba376686f3
4 changed files with 2916 additions and 2715 deletions

132
bench-graph.tmp.mjs Normal file
View File

@@ -0,0 +1,132 @@
import { readFileSync } from 'node:fs';
import { Graphviz } from '@hpcc-js/wasm-graphviz';
const src = readFileSync(
'/home/seb/src/dashdbschema/generate-schema-graph.js',
'utf8'
);
const parser = src.slice(
src.indexOf('function parseSchema'),
src.indexOf('const EDGE_COLORS')
);
const edgeColorsConst = src.slice(
src.indexOf('const EDGE_COLORS'),
src.indexOf('function edgeKey')
);
const edgeKeyFn = src.slice(
src.indexOf('function edgeKey'),
src.indexOf('/**\n * Only a spanning forest')
);
const ranking = src.slice(
src.indexOf('function selectRankingEdgeKeys'),
src.indexOf('function assignEdgeColors')
);
const edgeColors = src.slice(
src.indexOf('function assignEdgeColors'),
src.indexOf('function escapeHtml')
);
const escape = src.slice(
src.indexOf('function escapeHtml'),
src.indexOf('/**\n * Domain grouping')
);
const clusters = src.slice(
src.indexOf('const CLUSTERS'),
src.indexOf('const COLORS =')
);
const colors = src.slice(
src.indexOf('const COLORS ='),
src.indexOf('const COLORS =') +
src.slice(src.indexOf('const COLORS =')).indexOf('};') +
2
);
const orderMembers = src.slice(
src.indexOf('function orderClusterMembers'),
src.indexOf('function buildTableLabel')
);
const plainPositions = src.slice(
src.indexOf('function parsePlainPositions'),
src.indexOf('function flipCompassLR')
);
const reorder = src.slice(
src.indexOf('function reorderColumnsForCrossingReduction'),
src.indexOf('function parsePlainPositions')
);
const builder = src.slice(
src.indexOf('function buildTableLabel'),
src.indexOf('function countSvgCrossings')
);
const crossingsFn = src.slice(
src.indexOf('function countSvgCrossings'),
src.indexOf('/**\n * Graphviz self-edges')
);
const mod = await import(
'data:text/javascript,' +
encodeURIComponent(
parser +
'\n' +
edgeColorsConst +
'\n' +
clusters +
'\n' +
colors +
'\n' +
orderMembers +
'\n' +
plainPositions +
'\n' +
reorder +
'\n' +
edgeKeyFn +
'\n' +
ranking +
'\n' +
edgeColors +
'\n' +
escape +
'\n' +
builder +
'\n' +
crossingsFn +
'\nexport { parseSchema, buildDot, assignEdgeAnchors, parsePlainPositions, reorderColumnsForCrossingReduction, orderClusterMembers, CLUSTERS, COLORS, countSvgCrossings };'
)
);
const schemaSource = readFileSync(
'/home/seb/src/dashdbschema/src/providers/mssql/schema.js',
'utf8'
);
const { tables, edges } = mod.parseSchema(schemaSource);
const graphviz = await Graphviz.load();
let positions = null;
for (let pass = 0; pass < 3; pass++) {
const probeDot = mod.buildDot(tables, edges, positions);
const plain = graphviz.layout(probeDot, 'plain', 'dot');
positions = mod.parsePlainPositions(plain);
mod.reorderColumnsForCrossingReduction(tables, edges, positions);
}
const anchors = mod.assignEdgeAnchors(edges, positions);
const baseDot = mod.buildDot(tables, edges, positions, anchors);
const variants = [
['mclimit=4.0 splines=spline (current)', 'mclimit=4.0', 'splines=spline'],
['mclimit=1.0 splines=spline', 'mclimit=1.0', 'splines=spline'],
['mclimit=0.5 splines=spline', 'mclimit=0.5', 'splines=spline'],
['mclimit=1.0 splines=true', 'mclimit=1.0', 'splines=true'],
['mclimit=1.0 splines=polyline', 'mclimit=1.0', 'splines=polyline'],
];
for (const [label, mclimit, splines] of variants) {
const dot = baseDot
.replace('mclimit=4.0', mclimit)
.replace('splines=spline', splines);
const t = process.hrtime.bigint();
const svg = graphviz.layout(dot, 'svg', 'dot');
const ms = Number(process.hrtime.bigint() - t) / 1e6;
const t2 = process.hrtime.bigint();
const crossings = mod.countSvgCrossings(svg);
const cms = Number(process.hrtime.bigint() - t2) / 1e6;
console.log(
`${label}: layout=${ms.toFixed(0)}ms crossings=${crossings} (count=${cms.toFixed(0)}ms) total=${(ms + cms).toFixed(0)}ms`
);
}