## Dependency Resolver Performance Benchmarks ## ## This benchmark suite measures resolver performance across different ## package complexity levels and validates cache effectiveness. ## ## **Benchmark Categories:** ## - Simple packages (10-20 dependencies) ## - Complex packages (50-100 dependencies) ## - Massive packages (200+ dependencies) ## - Cache effectiveness (hit rates, speedup) ## ## **Metrics Tracked:** ## - Resolution time (cold cache) ## - Resolution time (warm cache) ## - Cache hit rate ## - Memory usage ## - Speedup factor import times import strformat import tables import ../src/nip/resolver/types import ../src/nip/resolver/graph_builder import ../src/nip/resolver/resolution_cache import ../src/nip/resolver/serialization import ../src/nip/cas/storage type BenchmarkResult* = object name*: string packageCount*: int dependencyCount*: int coldTime*: float # seconds warmTime*: float # seconds cacheHitRate*: float speedup*: float memoryUsed*: int # bytes BenchmarkSuite* = object results*: seq[BenchmarkResult] totalTime*: float # ============================================================================ # Test Data Generation # ============================================================================ proc generateSimplePackage*(name: string, depCount: int): PackageSpec = ## Generate simple package with linear dependencies result = PackageSpec( name: name, version: "1.0.0", dependencies: @[] ) for i in 0..= maxDepth: return for i in 0.. 0: coldTime / warmTime else: 0.0 let metrics = cache.getMetrics() echo fmt" Speedup: {speedup:.2f}x" echo fmt" Cache hit rate: {metrics.l1HitRate * 100:.2f}%" echo "" result = BenchmarkResult( name: name, packageCount: packageCount, dependencyCount: dependencyCount, coldTime: coldTime, warmTime: warmTime, cacheHitRate: metrics.l1HitRate, speedup: speedup, memoryUsed: 0 # TODO: Measure actual memory ) # ============================================================================ # Benchmark Suites # ============================================================================ proc runSimpleBenchmarks*(cache: ResolutionCache): seq[BenchmarkResult] = ## Run benchmarks for simple packages (10-20 dependencies) echo "=" .repeat(60) echo "SIMPLE PACKAGES (10-20 dependencies)" echo "=" .repeat(60) echo "" result = @[] # 10 dependencies let pkg10 = generateSimplePackage("simple-10", 10) result.add(benchmarkResolution("Simple 10 deps", pkg10, cache)) # 15 dependencies let pkg15 = generateSimplePackage("simple-15", 15) result.add(benchmarkResolution("Simple 15 deps", pkg15, cache)) # 20 dependencies let pkg20 = generateSimplePackage("simple-20", 20) result.add(benchmarkResolution("Simple 20 deps", pkg20, cache)) proc runComplexBenchmarks*(cache: ResolutionCache): seq[BenchmarkResult] = ## Run benchmarks for complex packages (50-100 dependencies) echo "=" .repeat(60) echo "COMPLEX PACKAGES (50-100 dependencies)" echo "=" .repeat(60) echo "" result = @[] # 50 dependencies let pkg50 = generateComplexPackage("complex-50", 50) result.add(benchmarkResolution("Complex 50 deps", pkg50, cache)) # 75 dependencies let pkg75 = generateComplexPackage("complex-75", 75) result.add(benchmarkResolution("Complex 75 deps", pkg75, cache)) # 100 dependencies let pkg100 = generateComplexPackage("complex-100", 100) result.add(benchmarkResolution("Complex 100 deps", pkg100, cache)) proc runMassiveBenchmarks*(cache: ResolutionCache): seq[BenchmarkResult] = ## Run benchmarks for massive packages (200+ dependencies) echo "=" .repeat(60) echo "MASSIVE PACKAGES (200+ dependencies)" echo "=" .repeat(60) echo "" result = @[] # 200 dependencies let pkg200 = generateMassivePackage("massive-200", 200) result.add(benchmarkResolution("Massive 200 deps", pkg200, cache)) # 300 dependencies let pkg300 = generateMassivePackage("massive-300", 300) result.add(benchmarkResolution("Massive 300 deps", pkg300, cache)) # 500 dependencies let pkg500 = generateMassivePackage("massive-500", 500) result.add(benchmarkResolution("Massive 500 deps", pkg500, cache)) # ============================================================================ # Results Reporting # ============================================================================ proc printSummary*(results: seq[BenchmarkResult]) = ## Print benchmark summary table echo "" echo "=" .repeat(80) echo "BENCHMARK SUMMARY" echo "=" .repeat(80) echo "" echo fmt"{'Benchmark':<25} {'Pkgs':>6} {'Deps':>6} {'Cold':>10} {'Warm':>10} {'Speedup':>8} {'Hit%':>6}" echo "-" .repeat(80) for result in results: echo fmt"{result.name:<25} {result.packageCount:>6} {result.dependencyCount:>6} " & fmt"{result.coldTime * 1000:>9.2f}ms {result.warmTime * 1000:>9.2f}ms " & fmt"{result.speedup:>7.2f}x {result.cacheHitRate * 100:>5.1f}%" echo "" # Calculate averages var avgColdTime = 0.0 var avgWarmTime = 0.0 var avgSpeedup = 0.0 var avgHitRate = 0.0 for result in results: avgColdTime += result.coldTime avgWarmTime += result.warmTime avgSpeedup += result.speedup avgHitRate += result.cacheHitRate let count = results.len.float avgColdTime /= count avgWarmTime /= count avgSpeedup /= count avgHitRate /= count echo fmt"{'AVERAGE':<25} {'':>6} {'':>6} " & fmt"{avgColdTime * 1000:>9.2f}ms {avgWarmTime * 1000:>9.2f}ms " & fmt"{avgSpeedup:>7.2f}x {avgHitRate * 100:>5.1f}%" echo "" proc exportResults*(results: seq[BenchmarkResult], filename: string) = ## Export benchmark results to CSV var csv = "Name,Packages,Dependencies,ColdTime(ms),WarmTime(ms),Speedup,HitRate(%)\n" for result in results: csv &= fmt"{result.name},{result.packageCount},{result.dependencyCount}," & fmt"{result.coldTime * 1000:.2f},{result.warmTime * 1000:.2f}," & fmt"{result.speedup:.2f},{result.cacheHitRate * 100:.2f}\n" writeFile(filename, csv) echo fmt"Results exported to: {filename}" # ============================================================================ # Main Benchmark Runner # ============================================================================ proc runAllBenchmarks*() = ## Run complete benchmark suite echo "" echo "╔" & "═".repeat(78) & "╗" echo "║" & " ".repeat(20) & "NIP DEPENDENCY RESOLVER BENCHMARKS" & " ".repeat(24) & "║" echo "╚" & "═".repeat(78) & "╝" echo "" let cas = newCASStorage("/tmp/benchmark-cas") let cache = newResolutionCache(cas, l1Capacity = 1000) var allResults: seq[BenchmarkResult] = @[] # Run benchmark suites allResults.add(runSimpleBenchmarks(cache)) allResults.add(runComplexBenchmarks(cache)) allResults.add(runMassiveBenchmarks(cache)) # Print summary printSummary(allResults) # Export results exportResults(allResults, "/tmp/benchmark-results.csv") echo "" echo "Benchmark complete!" echo "" # ============================================================================ # Entry Point # ============================================================================ when isMainModule: runAllBenchmarks()