Benchmark Notes — C# (Cross.Runtime.Bench.Csharp)¶
Correções Aplicadas¶
1. Warmup Insuficiente (CRÍTICO — Problema 1)¶
Sintoma: Todas as execuções apresentavam hasDrift: SuddenIncrease com magnitude +25% a +80%. Amostras finais sistematicamente mais lentas que as iniciais.
Causa raiz: O WarmupManager.ExecuteAdaptiveWarmup() podia declarar estabilidade após apenas 10-25 iterações, quando o JIT Tiered Compilation do .NET ainda não havia compilado Tier 1 (optimized). Background JIT ativo durante a medição causava drift.
Correção (WarmupManager.cs):
- Adicionada constante MinWarmupBeforeStabilityCheck = 50
- A verificação de CV% só ocorre após 50 iterações mínimas
- Isso garante que o JIT Tier 1 do .NET já compilou hot paths antes de verificar estabilidade
- Compatível com o mesmo piso aplicado em Java e Node.js
2. CPU% Inválida (CRÍTICO — Problema 2)¶
Sintoma: cpu_cpuPercent retornava valores absurdos: 15.000% a 30.000%.
Causa raiz: O cálculo (cpuTotalDelta / wallClockMs) * 100 acumulava tempo CPU de múltiplas threads sem normalizar pelo número de cores. Em uma máquina de 16 cores, um benchmark single-thread reportava ~1600%.
Correção (BenchmarkRunner.cs e CpuMetricsCollector.cs):
- Fórmula corrigida: cpuPercent = (userTimeMs + systemTimeMs) / (wallClockMs * ProcessorCount) * 100
- Produz 0-100% (single-core equivalent)
- Max clamping alterado de ProcessorCount * 100 para 100.0
- Mesma fórmula aplicada em:
- BenchmarkRunner.cs (cálculo principal)
- CpuMetricsCollector.TakeSample() (coleta periódica)
- CpuMetricsCollector.GetCpuUsagePercent() já estava correto
Como o Warmup Está Implementado¶
O warmup segue o padrão adaptativo (default) ou fixo:
Warmup Adaptativo (default)¶
- Executa a ação repetidamente com timer de alta precisão
- Após 50 iterações mínimas (MinWarmupBeforeStabilityCheck), inicia verificação
- A cada 5 iterações, calcula CV% das últimas N medições (janela = CvStabilityWindow)
- Se CV% < TargetCoefficientOfVariation (default 5%) por N verificações consecutivas → Para
- Caso contrário, continua até WarmupTimeSeconds (3s) ou WarmupIterations (100)
Warmup Fixo (AdaptiveWarmup = false)¶
- Executa exatamente WarmupIterations vezes sem verificação de estabilidade
Configurações por Preset¶
| Preset | WarmupIterations | WarmupTimeSeconds | Target CV% |
|---|---|---|---|
| Default | 100 | 3.0s | 5% |
| Fast | 10 | 1.0s | N/A (fixo) |
| HighPrecision | 200 | 10.0s | 2% |
Como CPU% É Calculada¶
Onde:
- cpuUserDelta = Process.UserProcessorTime (delta ms)
- cpuSystemDelta = Process.PrivilegedProcessorTime (delta ms)
- wallClockMs = Stopwatch.GetTimestamp() delta convertido para ms
- ProcessorCount = Environment.ProcessorCount
- Resultado: 0-100% (normalizado para single-core equivalent)
Como as Estatísticas São Agregadas¶
- Coleta: N medições via
Stopwatch.GetTimestamp()(nanosegundos) - Filtragem de Outliers: IQR (default), MAD, ZScore, ou Grubbs
- Algoritmo de Welford: Cálculo numericamente estável de média e variância
- Variância amostral: Bessel correction (N-1 divisor)
- IC 95%: t-Student com df = N-1 (não z-score)
- Detecção de Anomalias: Mann-Kendall test para drift, análise de GC e CPU
Métricas Exportadas¶
- Mean, Median, StdDev, Min, Max (ns e ms)
- CV% (Coefficient of Variation)
- IC 95% (Confidence Interval)
- Throughput (ops/sec)
- Outliers removidos + método