Evaluación comparativa y comparación de rendimiento
Resumen breve
El benchmarking es un experimento, no «ejecutar wrk durante 5 minutos». Principios básicos:1. Formular hipótesis y métricas.
2. Controlar las variables (hierro, núcleo, alimentación, ruido de fondo).
3. Recopile suficientes datos (réplicas, intervalos de confianza).
4. Lleve a cabo el perfilado - sin él no entender «por qué».
5. Haga repro: scripts, fijación de versiones y artefactos.
Objetivos de referencia y métricas de negocio
Ancho de banda (throughput): RPS/QPS/CPS, registros/sec.
Latencia (latency): p50/p95/p99/densidad de cola.
Eficiencia: Cost-per-1k RPS, vatios por transacción, $/milisegundos de mejora.
Estabilidad: jitter, variabilidad entre ciclos/nodos.
Elasticidad: cómo se escalan los indicadores en N × recursos (puntos de referencia de Amdahl/Gustafson).
Metodología: diseño del experimento
Hipótesis: «Envoy con HTTP/3 reducirá el p95 TTFB en un 10-15% con el mismo RPS».
Unidad de comparación: versión bilda/config/instance de hierro.
Circuito A/B: ejecución paralela en un entorno idéntico; o ABAB/Latin Square para reducir el impacto de la deriva.
Número de repeticiones: ≥ 10 rondas cortas + 3 largas por configuración para evaluaciones sostenidas.
Estadísticas: mediana, MAD, intervalos de confianza por butstrap; pruebas no paramétricas (Mann-Whitney) para distribuciones de cola.
DoE (mínimo): cambia una variable a la vez (OVAT) o un plan de factores fraccionados para 2-3 factores (por ejemplo, un perfil TLS × una versión HTTP × un núcleo).
Control de variables y ruidos
CPU governor: `performance`; desactivar «power save».
Turbo/Throttling: monitoreo de frecuencias, temperaturas y TNT (de lo contrario, el calentamiento dará falsas ganancias).
NUMA/Hyper-Threading: ancla el IRQ y los procesos ('taskset/numactl'), mide la localización de la memoria.
Balance C-states/IRQ: fijar la configuración; para pruebas de red - pin IRQ para núcleos específicos.
Procesos de fondo: nodo limpio, apagar cron/backup/antivirus/updatedb.
Red: rutas estables, MTU/ECN/AQM fijos, sin flatter de canal.
Datos: los mismos conjuntos, cardenalitos y distribuciones.
Caché: separe los modos «frío» (primer paso) y «cálido» (repetido), marque claramente.
Clases de referencia
1) Micro-benchmarks (función/algoritmo)
Objetivo: medir un código/algoritmo específico.
Herramientas: marcos de bench integrados (Go 'testing. B`, JMH, pytest-benchmark).
Reglas: calentamiento JIT, milisegundos → nanosegundos; aislamiento GC; seed fijo.
2) Meso-benchmarks (componente/servicio)
Servidor HTTP, caché, bróker, DB en un nodo.
Herramientas: wrk/wrk2, k6 (open model), vegeta, ghz (gRPC), fio, sysbench, iperf3.
Reglas: límites de conexiones/archivos, agrupaciones; Informe sobre la CPU/IRQ/GC.
3) Macro-benchmarks (e2e/ruta de consulta)
Ruta completa: CDN/edge → proxy → servicio → CD/caché → respuesta.
Herramientas: k6/Locust/Gatling + RUM/OTel treasing; una mezcla realista de rutas.
Reglas: más cerca de la realidad (datos «sucios», lagunas de sistemas externos), suavemente con retratos.
Conjunto de métricas por capa
Plantillas de prueba y comandos
Red (TCP/UDP):bash iperf3 -s # server iperf3 -c <host> -P 8 -t 60 # parallel, stable bandwidth
Servidor HTTP (carga estable, wrk2):
bash wrk2 -t8 -c512 -d5m -R 20000 https://api. example. com/endpoint \
--latency --timeout 2s
Modelo abierto (k6, arrival-rate):
javascript export const options = {
scenarios: { open: { executor: 'constant-arrival-rate', rate: 1000, timeUnit: '1s',
duration: '10m', preAllocatedVUs: 2000 } },
thresholds: { http_req_failed: ['rate<0. 3%'], http_req_duration: ['p(95)<250'] }
};
Disco (fio, 4k random read):
bash fio --name=randread --rw=randread --bs=4k --iodepth=64 --numjobs=4 \
--size=4G --runtime=120 --group_reporting --filename=/data/testfile
DB (sysbench + PostgreSQL idea aproximada):
bash sysbench oltp_read_write --table-size=1000000 --threads=64 \
--pgsql-host=... --pgsql-user=... --pgsql-password=... prepare sysbench oltp_read_write --time=600 --threads=64 run
Memoria/CPU (Linux perf + stress-ng):
bash perf stat -e cycles,instructions,cache-misses,L1-dcache-load-misses \
-- <your_binary> --bench
Estadísticas y validez
Repeticiones: mínimo de 10 carreras, excluir outliers (robustamente: mediana/MAD).
Intervalos de confianza: bootstrap 95% CI para p95/p99 y media.
Efecto-tamaño: cambio relativo y su CI (por ejemplo, −12% [−9%; −15%]).
Importancia práctica: reducir la p95 en un 10% a un precio de + 30% CPU - ¿vale la pena?
Gráficos: violin/ECDF para distribuciones, «curvas de saturación» (RPS→latency).
Creación de perfiles y localización de cuellos de botella
CPU: `perf`, `async-profiler`, eBPF/pyroscope; flamegraph antes y después.
Alloc/GC: perfiles runtime (Go pprof/Java JFR).
I/O: `iostat`, `blktrace`, `fio --lat_percentiles=1`.
Сеть: `ss -s`, `ethtool -S`, `dropwatch`, `tc -s qdisc`.
БД: `EXPLAIN (ANALYZE, BUFFERS)`, pg_stat_statements, slowlog.
Caché: teclas superiores, TTL, eviction causa.
Informes y artefactos
Qué fijar:- git SHA build, banderas de compilación/optimización.
- Configuraciones de núcleo/red (sysctl), versiones de controladores/NIC/firmware.
- Topología (vCPU/NUMA/HT), gobernador, temperatura/frecuencia.
- Datos: tamaño, cardenalito, distribuciones.
- Qué publicar: tablas p50/p95/p99, error/sec, throughput, recursos (CPU/RAM/IO), CI.
- Artefactos: scripts de ejecución, gráficos, flamegraph, resultados en bruto JSON/CSV, protocolo de entorno.
Comparaciones honestas (fair benchmarking)
Limitadores idénticos (conn pool, keepalive, cadenas TLS, OCSP stapling).
Los temporizadores/retraídas consistentes y la versión HTTP (h2/h3).
Balance de temperatura: calentamiento a equilibrio (sin efecto turbo-busto).
Cachés justos: o ambos «fríos» o ambos «cálidos».
Simetría de red: las mismas rutas/MTU/ECN/AQM.
Presupuesto de tiempo: DNS/TLS/connect - considerar explícitamente o excluir por igual.
Anti-patrones
Una carrera → «salida».
Mezcla de modos (parte fría, parte cálida) en una sola serie.
Un modelo cerrado en lugar de uno abierto a la carga de Internet → una falsa «estabilidad».
Retiros no contabilizados → «RPS está creciendo» a costa de tomas y 5xx en cascada.
Comparación en diferentes fierras/núcleos/hemisferios de energía.
Falta de perfilado → optimización «a ciegas».
Juego con GC/heap sin análisis de perfiles → regresión de cola.
Recetas prácticas
Pasos de paipline de bench mínimo:1. Fijar el entorno (script 'env _ capture. sh`).
2. Calentar (5-10 min), fijar frecuencias/temperaturas.
3. Realizar N repeticiones de corto + 1 larga carrera.
4. Quitar perfiles (CPU/alloc/IO) en su punto máximo.
5. Contar CI/gráficos, recoger artefactos.
6. Decisión: aceptar/rechazar la hipótesis, formar los pasos siguientes.
Curva de capacidad (capacity curve):- Pasos RPS (10% de paso) → fijamos p95/errores → encontramos «rodilla».
- Construimos un gráfico de RPS→latency y RPS→CPU: vemos la frontera y el coste de un porcentaje adicional.
Características específicas para iGaming/Fintech
Costo milisegundos: clasifique las mejoras por efecto $ (conversión/salida/límites PSP).
Picos (partidos/torneos): puntos de referencia de spike + plateau con calentamiento TLS/CDN/caché.
Pagos/PSP: medir el fin a fin con límites de sandbox, idempotencia y reacciones a la degradación; fijar Time-to-Wallet con métricas proxy.
Filtros antifraude/bot: incluir en el perfil de reglas macro-bench (false-positive-rate, suplemento latency).
Leaders/Jackpots: prueba teclas calientes/clasificación, bloqueos, atomicidad.
Lista de verificación
- Hipótesis/métricas/criterio de éxito.
- Control de variables (alimentación/NUMA/IRQ/red/caché).
- Plan de ejecución (réplicas, duración, calentamiento).
- Separación de modos «frío/cálido».
- Perfiles incluidos (CPU/alloc/IO/DB).
- Estadísticas: IC, pruebas de significación, gráficos.
- Artefactos y scripts repro en el repositorio (IaC para stand).
- Informe con «costo de mejora» y recomendaciones.
- Retest después de las optimizaciones (regression perf).
Mini informe (plantilla)
Objetivo: reducir la API p95 en un 15% sin crecimiento de CPU> 10%.
Método: A/B, k6 open-model 1k rps, 10 × 3 carreras, warm cache.
Total: p95 −12% [−9%; −15%], CPU + 6%, 5xx sin cambios.
Flamegraph: ↓ serialización JSON (−30% CPU), cuello de botella desplazado a la DB.
Decisión: adoptar la optimización; el siguiente paso es batchear las solicitudes de DB.
Artefactos: gráficos, perfiles, confecciones, crudos JSON.
Resultado
Un buen benchmarking es una metodología estricta + comparaciones honestas + validez estadística + perfilabilidad + reproducibilidad. Poner hipótesis, controlar el entorno, contar intervalos de confianza, publicar artefactos y tomar decisiones sobre el coste de la mejora. Así que no obtendrá una cifra hermosa en la presentación, sino un aumento real en la velocidad y previsibilidad de la plataforma.