ccusage-byobu
Version:
Real-time Claude Code API usage monitoring for byobu/tmux status bars with colored indicators, persistent caching, and automated integration
189 lines (158 loc) ⢠6.85 kB
JavaScript
/**
* Startup time benchmark - measures the effectiveness of lazy loading optimizations
*/
import { execSync } from 'child_process';
import { createTimer } from '../lib/performance.js';
/**
* Measure startup time by running the binary as a subprocess
* @param {string[]} args - Arguments to pass to ccusage-byobu
* @param {number} iterations - Number of iterations to run
* @returns {Object} Benchmark results
*/
function measureStartupTime(_args = [], iterations = 10) {
console.log(`š Measuring startup time with ${iterations} iterations...`);
const results = [];
const progressInterval = Math.max(1, Math.floor(iterations / 10));
for (let i = 0; i < iterations; i++) {
if (i % progressInterval === 0) {
process.stdout.write(` Progress: ${Math.round((i / iterations) * 100)}%\r`);
}
const timer = createTimer().start();
try {
// Run ccusage-byobu as subprocess to measure true startup time
execSync('node bin/ccusage-byobu.js', {
stdio: 'pipe', // Capture output
timeout: 10000, // 10 second timeout
env: { ...process.env, CCUSAGE_BYOBU_DEBUG: '0' }, // Disable debug output
});
} catch (error) {
// Expected for this test since we don't have real ccusage data
// Just measuring startup overhead
// Log errors when in debug mode to help with troubleshooting
if (
process.env.DEBUG ||
process.env.CCUSAGE_BYOBU_DEBUG === '1' ||
process.env.NODE_ENV === 'development'
) {
console.error(
`Debug: Caught error during startup measurement iteration ${i + 1}:`,
error.message
);
}
}
timer.stop();
results.push(timer.getDuration().milliseconds);
}
console.log(' Progress: 100% ');
// Calculate statistics
const avg = results.reduce((a, b) => a + b, 0) / results.length;
const min = Math.min(...results);
const max = Math.max(...results);
const sorted = [...results].sort((a, b) => a - b);
const p50 = sorted[Math.floor(sorted.length * 0.5)];
const p95 = sorted[Math.floor(sorted.length * 0.95)];
return {
iterations,
results,
stats: { avg, min, max, p50, p95 },
};
}
/**
* Compare startup times with and without lazy loading
*/
async function compareStartupTimes() {
console.log('š Startup Time Benchmark');
console.log('=========================\n');
// Parse command line arguments
const args = process.argv.slice(2);
const iterations = parseInt(
args.find((a) => a.startsWith('--iterations='))?.split('=')[1] || '20'
);
if (args.includes('--help')) {
console.log('Usage: startup-benchmark [options]');
console.log('\nOptions:');
console.log(' --iterations=N Number of iterations (default: 20)');
console.log(' --detailed Show detailed timing breakdown');
console.log('\nThis tool measures startup time to quantify lazy loading improvements.');
process.exit(0);
}
// Measure current startup time (with lazy loading)
console.log('š Testing current implementation (with lazy loading):');
const currentResults = measureStartupTime([], iterations);
console.log('\nš Results with lazy loading:');
console.log(` Average: ${currentResults.stats.avg.toFixed(2)}ms`);
console.log(` Min: ${currentResults.stats.min.toFixed(2)}ms`);
console.log(` Max: ${currentResults.stats.max.toFixed(2)}ms`);
console.log(` P50: ${currentResults.stats.p50.toFixed(2)}ms`);
console.log(` P95: ${currentResults.stats.p95.toFixed(2)}ms`);
// Show detailed module loading analysis
if (args.includes('--detailed')) {
console.log('\nš Detailed Startup Analysis:');
// Test with debug output to see module loading
try {
const debugOutput = execSync('node bin/ccusage-byobu.js', {
encoding: 'utf-8',
timeout: 5000,
env: { ...process.env, CCUSAGE_BYOBU_DEBUG: '1' },
stdio: 'pipe',
});
const lines = debugOutput.split('\n');
const startupLine = lines.find((line) => line.includes('Startup time:'));
const memoryLine = lines.find((line) => line.includes('Startup memory:'));
const modulesLine = lines.find((line) => line.includes('Modules loaded:'));
if (startupLine) console.log(` ${startupLine}`);
if (memoryLine) console.log(` ${memoryLine}`);
if (modulesLine) console.log(` ${modulesLine}`);
} catch (error) {
console.log(' Debug analysis unavailable');
// Log errors when in debug mode to help with troubleshooting
if (
process.env.DEBUG ||
process.env.CCUSAGE_BYOBU_DEBUG === '1' ||
process.env.NODE_ENV === 'development'
) {
console.error('Debug: Error during detailed analysis:', error.message);
}
}
}
// Simulate startup time without lazy loading (theoretical)
const estimatedModuleLoadingOverhead = 50; // Estimated ms overhead from loading all modules
const theoreticalNonLazyAvg = currentResults.stats.avg + estimatedModuleLoadingOverhead;
console.log('\nš Estimated Lazy Loading Benefits:');
console.log(` Current avg (with lazy loading): ${currentResults.stats.avg.toFixed(2)}ms`);
console.log(` Estimated without lazy loading: ~${theoreticalNonLazyAvg.toFixed(2)}ms`);
const improvement =
((theoreticalNonLazyAvg - currentResults.stats.avg) / theoreticalNonLazyAvg) * 100;
console.log(` Estimated improvement: ~${improvement.toFixed(1)}% faster startup`);
console.log(` Time saved per startup: ~${estimatedModuleLoadingOverhead}ms`);
// Performance recommendations
console.log('\nš” Performance Analysis:');
if (currentResults.stats.avg < 100) {
console.log(' ā
Startup time is excellent (<100ms)');
} else if (currentResults.stats.avg < 300) {
console.log(' ā
Startup time is good (<300ms)');
} else if (currentResults.stats.avg < 500) {
console.log(' ā ļø Startup time is acceptable but could be improved');
} else {
console.log(' ā Startup time is slow, consider further optimizations');
}
// Variance analysis
const variance =
currentResults.results.reduce((sum, val) => {
const diff = val - currentResults.stats.avg;
return sum + diff * diff;
}, 0) / currentResults.results.length;
const stdDev = Math.sqrt(variance);
console.log(` Consistency: ±${stdDev.toFixed(2)}ms standard deviation`);
if (stdDev < 20) {
console.log(' ā
Very consistent startup times');
} else if (stdDev < 50) {
console.log(' ā
Reasonably consistent startup times');
} else {
console.log(' ā ļø High variance in startup times - investigate environmental factors');
}
console.log('\nā
Startup benchmark complete!');
}
// Run the benchmark
compareStartupTimes().catch(console.error);