wifi-densepose/vendor/sublinear-time-solver/tests/performance/test-fast-solver.js

196 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Test and benchmark the fast solver implementation
* Goal: Beat Python benchmarks that show MCP Dense is 190x slower
*/
import { FastSolver, FastCSRMatrix } from './js/fast-solver.js';
function testBasicSolver() {
console.log('🧪 Testing Fast Solver Basic Functionality...\n');
// Create a simple 2x2 test matrix
const triplets = [
[0, 0, 4.0], [0, 1, 1.0],
[1, 0, 1.0], [1, 1, 3.0]
];
const matrix = FastCSRMatrix.fromTriplets(triplets, 2, 2);
const b = [1.0, 2.0];
const solver = new FastSolver();
const result = solver.solve(matrix, b);
console.log('Input matrix (2x2):');
console.log(' [4.0, 1.0]');
console.log(' [1.0, 3.0]');
console.log(`Right-hand side: [${b.join(', ')}]`);
console.log(`Solution: [${result.solution.map(x => x.toFixed(6)).join(', ')}]`);
console.log(`Execution time: ${result.executionTime.toFixed(3)}ms`);
console.log(`Method: ${result.method}`);
// Verify solution
const y = new Float64Array(2);
matrix.multiplyVector(result.solution, y);
const error = Math.sqrt((y[0] - b[0])**2 + (y[1] - b[1])**2);
console.log(`Verification error: ${error.toFixed(2e-10)}`);
console.log(error < 1e-8 ? '✅ PASSED' : '❌ FAILED');
return error < 1e-8;
}
function benchmarkAgainstPython() {
console.log('\n🏃 Benchmarking Against Python Baselines...\n');
const solver = new FastSolver();
// Test the critical sizes from the performance analysis
const results = solver.benchmark([100, 1000]);
console.log('\n📈 Summary Results:');
console.log('Size\tTime(ms)\tPython(ms)\tSpeedup\tStatus');
console.log('-'.repeat(50));
let totalSpeedup = 0;
let passedTests = 0;
for (const result of results) {
const status = result.speedup > 1.0 ? '✅ WIN' : '❌ LOSE';
console.log(`${result.size}\t${result.timeMs.toFixed(1)}\t\t${result.pythonBaseline}\t\t${result.speedup.toFixed(1)}x\t${status}`);
totalSpeedup += result.speedup;
if (result.speedup > 1.0) passedTests++;
}
const avgSpeedup = totalSpeedup / results.length;
console.log(`\nAverage speedup: ${avgSpeedup.toFixed(2)}x`);
console.log(`Tests passed: ${passedTests}/${results.length}`);
return { results, avgSpeedup, passedTests };
}
function testMemoryEfficiency() {
console.log('\n💾 Testing Memory Efficiency...\n');
const solver = new FastSolver();
const startMemory = process.memoryUsage().heapUsed;
// Test with 10K matrix (should use < 1MB according to targets)
console.log('Creating 10,000x10,000 sparse matrix...');
const { matrix, b } = solver.generateTestMatrix(10000, 0.0001); // Very sparse
const afterMatrixMemory = process.memoryUsage().heapUsed;
const matrixMemory = (afterMatrixMemory - startMemory) / 1024 / 1024; // MB
console.log(`Matrix memory usage: ${matrixMemory.toFixed(2)} MB`);
console.log(`Target: < 1 MB`);
console.log(`NNZ: ${matrix.nnz.toLocaleString()}`);
console.log(`Sparsity: ${(matrix.nnz / (10000 * 10000) * 100).toFixed(4)}%`);
// Test solve
console.log('\nSolving 10Kx10K system...');
const startTime = process.hrtime.bigint();
const result = solver.solve(matrix, b);
const endTime = process.hrtime.bigint();
const solveTime = Number(endTime - startTime) / 1e6;
const finalMemory = process.memoryUsage().heapUsed;
const totalMemory = (finalMemory - startMemory) / 1024 / 1024;
console.log(`Solve time: ${solveTime.toFixed(1)}ms`);
console.log(`Total memory: ${totalMemory.toFixed(2)} MB`);
console.log(`Memory target: < 1 MB - ${totalMemory < 1.0 ? '✅ PASSED' : '❌ FAILED'}`);
return { matrixMemory, totalMemory, solveTime, passed: totalMemory < 1.0 };
}
function testTargetPerformance() {
console.log('\n🎯 Testing Target Performance Metrics...\n');
const solver = new FastSolver();
// Target: 100K×100K system solutions in < 150ms
console.log('Testing 100K×100K performance target...');
const { matrix, b } = solver.generateTestMatrix(100000, 0.00001); // Ultra sparse
console.log(`Matrix size: ${matrix.rows}x${matrix.cols}`);
console.log(`NNZ: ${matrix.nnz.toLocaleString()}`);
console.log(`Sparsity: ${(matrix.nnz / (100000 * 100000) * 100).toFixed(6)}%`);
const startTime = process.hrtime.bigint();
const result = solver.solve(matrix, b);
const endTime = process.hrtime.bigint();
const timeMs = Number(endTime - startTime) / 1e6;
const target = 150; // ms
console.log(`Execution time: ${timeMs.toFixed(1)}ms`);
console.log(`Target: < ${target}ms`);
console.log(`Status: ${timeMs < target ? '✅ PASSED' : '❌ FAILED'}`);
console.log(`Method: ${result.method}`);
return { timeMs, target, passed: timeMs < target };
}
async function main() {
console.log('🚀 Fast Solver Performance Validation');
console.log('Targeting Python benchmark improvements');
console.log('=' * 60);
const results = {
basic: false,
benchmark: { avgSpeedup: 0, passedTests: 0 },
memory: { passed: false },
target: { passed: false }
};
try {
// Basic functionality test
results.basic = testBasicSolver();
// Benchmark against Python
const benchmarkResult = benchmarkAgainstPython();
results.benchmark = benchmarkResult;
// Memory efficiency test
const memoryResult = testMemoryEfficiency();
results.memory = memoryResult;
// Target performance test
const targetResult = testTargetPerformance();
results.target = targetResult;
// Summary
console.log('\n🏆 FINAL RESULTS');
console.log('=' * 60);
console.log(`Basic functionality: ${results.basic ? '✅ PASS' : '❌ FAIL'}`);
console.log(`Python benchmark: ${results.benchmark.avgSpeedup.toFixed(2)}x speedup (${results.benchmark.passedTests}/2 tests passed)`);
console.log(`Memory efficiency: ${results.memory.passed ? '✅ PASS' : '❌ FAIL'}`);
console.log(`Target performance: ${results.target.passed ? '✅ PASS' : '❌ FAIL'}`);
const overallScore = (
(results.basic ? 25 : 0) +
(results.benchmark.passedTests * 12.5) +
(results.memory.passed ? 25 : 0) +
(results.target.passed ? 25 : 0)
);
console.log(`\nOverall Score: ${overallScore}/100`);
if (overallScore >= 75) {
console.log('🎉 EXCELLENT: Ready for production deployment!');
} else if (overallScore >= 50) {
console.log('⚠️ GOOD: Some optimizations still needed');
} else {
console.log('❌ NEEDS WORK: Significant performance improvements required');
}
} catch (error) {
console.error('❌ Test failed with error:', error.message);
console.error(error.stack);
process.exit(1);
}
}
main();