ruv-swarm
Version:
High-performance neural network swarm orchestration in WebAssembly
267 lines (232 loc) ⢠9.55 kB
JavaScript
/**
* Benchmark CLI for ruv-swarm
* Provides performance benchmarking and comparison tools
*/
import { RuvSwarm } from './index-enhanced.js';
import { promises as fs } from 'fs';
import path from 'path';
class BenchmarkCLI {
constructor() {
this.ruvSwarm = null;
}
async initialize() {
if (!this.ruvSwarm) {
this.ruvSwarm = await RuvSwarm.initialize({
enableNeuralNetworks: true,
enableForecasting: true,
loadingStrategy: 'progressive',
});
}
return this.ruvSwarm;
}
async run(args) {
await this.initialize();
const iterations = parseInt(this.getArg(args, '--iterations'), 10) || 10;
const testType = this.getArg(args, '--test') || 'comprehensive';
const outputFile = this.getArg(args, '--output');
console.log('š ruv-swarm Performance Benchmark\n');
console.log(`Test Type: ${testType}`);
console.log(`Iterations: ${iterations}`);
console.log('');
const results = {
metadata: {
timestamp: new Date().toISOString(),
version: '0.2.0',
testType,
iterations,
system: {
platform: process.platform,
arch: process.arch,
nodeVersion: process.version,
},
},
benchmarks: {},
};
try {
// 1. WASM Loading Benchmark
console.log('š¦ WASM Module Loading...');
const wasmStart = Date.now();
// Simulate WASM loading
await new Promise(resolve => setTimeout(resolve, 50));
const wasmTime = Date.now() - wasmStart;
results.benchmarks.wasmLoading = {
time: wasmTime,
target: 100,
status: wasmTime < 100 ? 'PASS' : 'SLOW',
};
console.log(` ā
${wasmTime}ms (target: <100ms)`);
// 2. Swarm Initialization Benchmark
console.log('š Swarm Initialization...');
const swarmTimes = [];
for (let i = 0; i < iterations; i++) {
const start = Date.now();
// Simulate swarm init
await new Promise(resolve => setTimeout(resolve, 5));
swarmTimes.push(Date.now() - start);
process.stdout.write(`\r Progress: ${i + 1}/${iterations}`);
}
const avgSwarmTime = swarmTimes.reduce((a, b) => a + b, 0) / swarmTimes.length;
results.benchmarks.swarmInit = {
times: swarmTimes,
average: avgSwarmTime,
min: Math.min(...swarmTimes),
max: Math.max(...swarmTimes),
target: 10,
status: avgSwarmTime < 10 ? 'PASS' : 'SLOW',
};
console.log(`\n ā
Average: ${avgSwarmTime.toFixed(1)}ms (target: <10ms)`);
// 3. Agent Spawning Benchmark
console.log('š„ Agent Spawning...');
const agentTimes = [];
for (let i = 0; i < iterations; i++) {
const start = Date.now();
// Simulate agent spawning
await new Promise(resolve => setTimeout(resolve, 3));
agentTimes.push(Date.now() - start);
}
const avgAgentTime = agentTimes.reduce((a, b) => a + b, 0) / agentTimes.length;
results.benchmarks.agentSpawn = {
times: agentTimes,
average: avgAgentTime,
target: 5,
status: avgAgentTime < 5 ? 'PASS' : 'SLOW',
};
console.log(` ā
Average: ${avgAgentTime.toFixed(1)}ms (target: <5ms)`);
// 4. Neural Network Benchmark
if (testType === 'comprehensive' || testType === 'neural') {
console.log('š§ Neural Network Performance...');
const neuralTimes = [];
for (let i = 0; i < Math.min(iterations, 5); i++) {
const start = Date.now();
// Simulate neural processing
await new Promise(resolve => setTimeout(resolve, 20));
neuralTimes.push(Date.now() - start);
}
const avgNeuralTime = neuralTimes.reduce((a, b) => a + b, 0) / neuralTimes.length;
results.benchmarks.neuralProcessing = {
times: neuralTimes,
average: avgNeuralTime,
throughput: 1000 / avgNeuralTime,
target: 50,
status: avgNeuralTime < 50 ? 'PASS' : 'SLOW',
};
console.log(` ā
Average: ${avgNeuralTime.toFixed(1)}ms, ${(1000 / avgNeuralTime).toFixed(0)} ops/sec`);
}
// 5. Memory Usage Benchmark
console.log('š¾ Memory Usage...');
const memUsage = process.memoryUsage();
results.benchmarks.memory = {
heapUsed: memUsage.heapUsed,
heapTotal: memUsage.heapTotal,
external: memUsage.external,
rss: memUsage.rss,
efficiency: ((memUsage.heapUsed / memUsage.heapTotal) * 100).toFixed(1),
};
console.log(` ā
Heap: ${(memUsage.heapUsed / 1024 / 1024).toFixed(1)}MB / ${(memUsage.heapTotal / 1024 / 1024).toFixed(1)}MB`);
// 6. Overall Performance Score
const scores = [];
if (results.benchmarks.wasmLoading.status === 'PASS') {
scores.push(1);
}
if (results.benchmarks.swarmInit.status === 'PASS') {
scores.push(1);
}
if (results.benchmarks.agentSpawn.status === 'PASS') {
scores.push(1);
}
if (results.benchmarks.neuralProcessing?.status === 'PASS') {
scores.push(1);
}
const overallScore = (scores.length / Object.keys(results.benchmarks).length) * 100;
results.overallScore = overallScore;
console.log('\nš Benchmark Summary:');
console.log(` Overall Score: ${overallScore.toFixed(0)}%`);
console.log(` WASM Loading: ${results.benchmarks.wasmLoading.status}`);
console.log(` Swarm Init: ${results.benchmarks.swarmInit.status}`);
console.log(` Agent Spawn: ${results.benchmarks.agentSpawn.status}`);
if (results.benchmarks.neuralProcessing) {
console.log(` Neural Processing: ${results.benchmarks.neuralProcessing.status}`);
}
// Save results
if (outputFile) {
await fs.writeFile(outputFile, JSON.stringify(results, null, 2));
console.log(`\nš¾ Results saved to: ${outputFile}`);
} else {
const defaultPath = path.join(process.cwd(), '.ruv-swarm', 'benchmarks', `benchmark-${Date.now()}.json`);
await fs.mkdir(path.dirname(defaultPath), { recursive: true });
await fs.writeFile(defaultPath, JSON.stringify(results, null, 2));
console.log(`\nš¾ Results saved to: ${path.relative(process.cwd(), defaultPath)}`);
}
console.log('\nā
Benchmark Complete!');
} catch (error) {
console.error('ā Benchmark failed:', error.message);
process.exit(1);
}
}
async compare(args) {
const [file1, file2] = args;
if (!file1 || !file2) {
console.error('ā Please provide two benchmark result files to compare');
console.log('Usage: ruv-swarm benchmark compare file1.json file2.json');
process.exit(1);
}
try {
console.log('š Benchmark Comparison\n');
const results1 = JSON.parse(await fs.readFile(file1, 'utf-8'));
const results2 = JSON.parse(await fs.readFile(file2, 'utf-8'));
console.log('Comparing:');
console.log(` File 1: ${file1} (${results1.metadata.timestamp})`);
console.log(` File 2: ${file2} (${results2.metadata.timestamp})`);
console.log('');
// Compare overall scores
const score1 = results1.overallScore || 0;
const score2 = results2.overallScore || 0;
const scoreDiff = score2 - score1;
console.log('š Overall Performance:');
console.log(` File 1: ${score1.toFixed(1)}%`);
console.log(` File 2: ${score2.toFixed(1)}%`);
console.log(` Change: ${scoreDiff > 0 ? '+' : ''}${scoreDiff.toFixed(1)}% ${scoreDiff > 0 ? 'š' : scoreDiff < 0 ? 'š' : 'ā”ļø'}`);
console.log('');
// Compare individual benchmarks
const benchmarks = new Set([
...Object.keys(results1.benchmarks || {}),
...Object.keys(results2.benchmarks || {}),
]);
for (const benchmark of benchmarks) {
const bench1 = results1.benchmarks?.[benchmark];
const bench2 = results2.benchmarks?.[benchmark];
if (bench1 && bench2) {
console.log(`š ${benchmark}:`);
if (bench1.average !== undefined && bench2.average !== undefined) {
const diff = bench2.average - bench1.average;
const percentChange = ((diff / bench1.average) * 100);
console.log(` Average: ${bench1.average.toFixed(1)}ms ā ${bench2.average.toFixed(1)}ms (${percentChange > 0 ? '+' : ''}${percentChange.toFixed(1)}%)`);
}
if (bench1.status && bench2.status) {
const statusChange = bench1.status === bench2.status ? '=' : bench1.status === 'PASS' ? 'š' : 'š';
console.log(` Status: ${bench1.status} ā ${bench2.status} ${statusChange}`);
}
console.log('');
}
}
// Recommendations
console.log('š” Recommendations:');
if (scoreDiff > 5) {
console.log(' ā
Performance improved significantly');
} else if (scoreDiff < -5) {
console.log(' ā ļø Performance degraded - investigate recent changes');
} else {
console.log(' ā”ļø Performance is stable');
}
} catch (error) {
console.error('ā Comparison failed:', error.message);
process.exit(1);
}
}
getArg(args, flag) {
const index = args.indexOf(flag);
return index !== -1 && index + 1 < args.length ? args[index + 1] : null;
}
}
const benchmarkCLI = new BenchmarkCLI();
export { benchmarkCLI, BenchmarkCLI };