import { performance } from 'node:perf_hooks'; import { Arbiter } from '../src/core/Arbiter.js'; import { PartialGraphContext } from '../src/core/PartialGraphContext.js'; import { validateClaimsForLayer } from '../src/core/partial-graph/layer-registry.js'; function percentile(sorted, p) { if (!sorted.length) return 0; const idx = Math.min(sorted.length - 1, Math.max(0, Math.floor(sorted.length * p) - 1)); return sorted[idx]; } function summarize(name, durations) { const sorted = [...durations].sort((a, b) => a - b); const avg = durations.reduce((a, b) => a + b, 0) / durations.length; const p95 = percentile(sorted, 0.95); const p99 = percentile(sorted, 0.99); console.log(`${name}: avg=${avg.toFixed(4)}ms p95=${p95.toFixed(4)}ms p99=${p99.toFixed(4)}ms`); } function benchmarkLayerRegistry(iterations = 20000) { const claims = [ { relation: 'delegated_authority', object: 'resource:alpha:item:1', ttl_seconds: 60 }, { relation: 'workflow_step', object: 'workflow:loan:step:2', ttl_seconds: 60 } ]; const durations = []; for (let i = 0; i < iterations; i++) { const start = performance.now(); validateClaimsForLayer('workflow_overlay', claims, ['delegated_authority', 'workflow_step']); durations.push(performance.now() - start); } summarize('layer_registry.validate', durations); } function benchmarkPartialGraphLookup(iterations = 20000) { const arbiter = new Arbiter(); arbiter.addNode('user:1', 'user'); arbiter.addNode('doc:1', 'doc'); const context = new PartialGraphContext(arbiter, { relations: [{ src: 'user:1', relation: 'can_read', dst: 'doc:1', possibility: 1.0 }] }); const srcId = context.nodeIdByKey.get('user:1'); const dstId = context.nodeIdByKey.get('doc:1'); const durations = []; for (let i = 0; i < iterations; i++) { const start = performance.now(); context.getDirectRelation(srcId, 'can_read', dstId); durations.push(performance.now() - start); } summarize('partial_graph_context.get_direct_relation', durations); } function benchmarkArbiterCheck(iterations = 10000) { const arbiter = new Arbiter(); arbiter.addNode('user:1', 'user'); arbiter.addNode('doc:1', 'doc'); arbiter.setRelationConfig('can_read', { type: 'direct' }); arbiter.addRelation('user:1', 'can_read', 'doc:1', 1.0); const durations = []; for (let i = 0; i < iterations; i++) { const start = performance.now(); arbiter.check('user:1', 'can_read', 'doc:1'); durations.push(performance.now() - start); } summarize('arbiter.check_direct', durations); } console.log('Core performance benchmark'); benchmarkLayerRegistry(); benchmarkPartialGraphLookup(); benchmarkArbiterCheck();