# SPDX-License-Identifier: LSL-1.0 # Copyright (c) 2026 Markus Maiwald # Stewardship: Self Sovereign Society Foundation # # This file is part of the Nexus Sovereign Core. # See legal/LICENSE_SOVEREIGN.md for license terms. ## NimPak Performance Benchmarking ## ## Comprehensive benchmarks for the NimPak package manager. ## Task 43: Performance benchmarking. import std/[os, strutils, strformat, times, random, json, stats, sequtils] import cas type BenchmarkResult* = object name*: string iterations*: int totalTime*: float # Total time in seconds avgTime*: float # Average time per operation in ms minTime*: float # Minimum time in ms maxTime*: float # Maximum time in ms stdDev*: float # Standard deviation in ms opsPerSec*: float # Operations per second bytesProcessed*: int64 # Total bytes processed throughputMBps*: float # Throughput in MB/s BenchmarkSuite* = object name*: string results*: seq[BenchmarkResult] startTime*: DateTime endTime*: DateTime # ############################################################################ # Benchmark Utilities # ############################################################################ proc calculateStats*(times: seq[float], iterations: int): BenchmarkResult = ## Calculate statistics from timing data result.iterations = iterations result.totalTime = times.foldl(a + b, 0.0) / 1000.0 # Total in seconds result.avgTime = mean(times) result.minTime = min(times) result.maxTime = max(times) if times.len > 1: result.stdDev = standardDeviation(times) else: result.stdDev = 0.0 if result.totalTime > 0: result.opsPerSec = float(iterations) / result.totalTime else: result.opsPerSec = 0.0 proc formatBenchmarkResult*(r: BenchmarkResult): string = ## Format a benchmark result for display result = fmt""" {r.name}: Iterations: {r.iterations} Total time: {r.totalTime:.3f}s Avg time: {r.avgTime:.3f}ms Min time: {r.minTime:.3f}ms Max time: {r.maxTime:.3f}ms Std dev: {r.stdDev:.3f}ms Ops/sec: {r.opsPerSec:.0f}""" if r.bytesProcessed > 0: result.add fmt""" Throughput: {r.throughputMBps:.2f} MB/s""" # ############################################################################ # CAS Benchmarks # ############################################################################ proc benchmarkCasStore*(casManager: var CasManager, dataSize: int, iterations: int): BenchmarkResult = ## Benchmark CAS store operation var times: seq[float] = @[] for i in 1..iterations: var testData = newSeq[byte](dataSize) randomize() for j in 0.. 0: result.throughputMBps = float(result.bytesProcessed) / (result.totalTime * 1024 * 1024) proc benchmarkCasRetrieve*(casManager: var CasManager, dataSize: int, iterations: int): BenchmarkResult = ## Benchmark CAS retrieve operation var testData = newSeq[byte](dataSize) for i in 0.. 0: result.throughputMBps = float(result.bytesProcessed) / (result.totalTime * 1024 * 1024) proc benchmarkCasExists*(casManager: var CasManager, iterations: int): BenchmarkResult = ## Benchmark CAS existence check let testData = @[byte(1), byte(2), byte(3)] let storeResult = casManager.storeObject(testData) let existingHash = storeResult.get().hash let nonExistingHash = "xxh3-nonexistent0000000000000000" var times: seq[float] = @[] var checkExisting = true for i in 1..iterations: let startTime = epochTime() if checkExisting: discard casManager.objectExists(existingHash) else: discard casManager.objectExists(nonExistingHash) let endTime = epochTime() times.add((endTime - startTime) * 1000.0) checkExisting = not checkExisting result = calculateStats(times, iterations) result.name = "CAS Exists Check" proc benchmarkCasHash*(dataSize: int, iterations: int): BenchmarkResult = ## Benchmark hash calculation (without storage) var testData = newSeq[byte](dataSize) for i in 0.. 0: result.throughputMBps = float(result.bytesProcessed) / (result.totalTime * 1024 * 1024) # ############################################################################ # Deduplication Benchmarks # ############################################################################ proc benchmarkDeduplication*(casManager: var CasManager, chunkSize: int, duplicateRatio: float, iterations: int): BenchmarkResult = ## Benchmark deduplication with varying duplicate ratios var chunks: seq[seq[byte]] = @[] var uniqueChunks = max(1, int(float(iterations) * (1.0 - duplicateRatio))) # Generate unique chunks for i in 0..9.2f} | 1.00x | | Flatpak | {flatpakTime:>9.2f} | {nipResults.avgTime/flatpakTime:.2f}x | | Snap | {snapTime:>9.2f} | {nipResults.avgTime/snapTime:.2f}x | | Docker | {dockerTime:>9.2f} | {nipResults.avgTime/dockerTime:.2f}x | """