Cifras con sus condiciones.
Builds Release en un Intel i7-6700 (Skylake, AVX2, 4 núcleos): Windows x64 con MSVC 19.51 y Linux x64 en WSL2 con GCC 15.2. Algunas líneas base antiguas se registraron con MSVC 19.44 y GCC 13.3, y el README de cada módulo indica su compilador. Las cifras son medianas o el mejor de varios intentos, según indique cada README. Cuando aparecen dos cifras, Windows va primero. Cuando aparece una sola, la fila indica la plataforma.
Rendimiento de datos
Latencia
| Operación | Módulo | Medido |
|---|---|---|
| Emitir una señal sin oyentes | event | 0.54 ns |
| Tick del planificador en reposo, con el reloj ya leído | scheduler | 1.97 / 0.71 ns |
| Buscar un mensaje traducido | i18n | 1.4 a 2.6 ns |
| Propiedades Unicode de un code point | text | 2.2 / 2.6 ns |
| Lectura de config por handle | config | 3.52 ns |
| Incrementar un contador de telemetría | telemetría | 4.88 a 4.98 ns |
| Cambio de fibra en bruto, Windows | coroutine | 16 a 18 ns |
| Leer el reloj monotónico | time | 18.75 / 22.00 ns |
| Armar un temporizador con un millón ya activos | time | 20 a 23 ns |
| Llamada RPC unaria, transporte nulo, Windows | rpc | 617 a 714 ns |
| Abrir un almacén clave-valor de 1 GB tras un cierre limpio | storage | 1.49 / 0.92 ms |
Frente a las referencias
Regex vs std::regex. De 10× a 351× más rápido que libstdc++ en seis de siete patrones (8× en el séptimo), de 1.3× a 42× más rápido que el de MSVC, en tiempo lineal. std::regex se ejecuta sobre 512 KB del mismo texto de 2 MB, con el resultado escalado.
Formateo de enteros vs snprintf. 5.4× más rápido. Aparte, el escritor de terminal convierte 100,000 escrituras de un byte en /dev/null en 25 llamadas a write.
Búsqueda vectorial vs hnswlib 0.8. SIFT1M, un hilo, Linux: recall@10 de 0.9633 frente a 0.9634 con un rendimiento comparable (de 4,485 a 5,663 frente a 4,624 consultas/s), índice construido en 478 s frente a 525 s.
Matemáticas AVX2 vs escalares. Normalización por lotes en estructura de arrays, 512 puntos en L1: 8.1× / 9.0× sobre la ruta escalar, que se compila sin autovectorización. Todas las rutas devuelven los mismos bits, sin contracción FMA.
Contrastado con código que no escribimos.
| Qué | Contrastado con | Resultado |
|---|---|---|
| Ed25519 | OpenSSL, una referencia Python con enteros exactos y los vectores de RFC 8032 | 11,848 · 0 divergencias |
| SHA-384/512, HMAC, HKDF, AES-GCM | Python cryptography 46 y hashlib sobre OpenSSL 3.5, más 47 vectores oficiales | 127,502 · 0 divergencias |
| X25519, P-256, P-384, verificación RSA | los mismos oráculos y RFC 7748 y 6979 | 59,001 · 0 divergencias |
| X.509 | openssl verify y Python cryptography, cadenas aleatorias | 23,643 |
| TLS 1.3 | traza de RFC 8448, openssl s_server y s_client, Python ssl | 31 casos · 0 fallos |
| Compresión | liblz4, zlib y libxxhash, en Linux | 79,864 · 0 divergencias |
| Unicode 18 | los archivos de conformidad oficiales de Unicode | 100% |
| Machine learning | scikit-learn, LightGBM, XGBoost, ONNX Runtime, hnswlib, scipy | dentro de 1e-4 o bit a bit, y el recall de hnswlib |
| Telemetría | Prometheus y OpenTelemetry Collector reales | aceptado, sin rechazos |
| Build | Tests |
|---|---|
| Windows x64, MSVC 19.51, Release | 282 de 282 |
| Linux x64, GCC 15.2, Release | 284 de 284 |
| Linux x64, Guard y ML activados | 287 de 287 |
| Linux x64, ASan y UBSan | 274 · limpio, 17 oct |
| Linux x64, TSan | 274 de 274 · limpio, 17 oct |
Los scripts de mutación siembran el error y exigen que el test falle. Así se detectaron una clave de ofuscación que se anulaba a sí misma y un caso de falsificación Ed25519 mientras todos los tests de ida y vuelta pasaban.
Un proyecto aparte se compila contra el SDK empaquetado con find_package, tal como lo usa un cliente. Cada header público compila por sí solo, en MSVC y GCC.
MSVC /W4 y GCC -Wall -Wextra, incluidos los árboles con sanitizers.
Dónde funciona, sin rodeos.
24 objetivos que no hemos alcanzado. Todavía.
Cada módulo tiene su propia especificación con objetivos de rendimiento. Estos son los que sus mediciones no alcanzaron, tal como consta en la documentación del módulo. Mejor leerlos aquí que descubrirlos en producción.
| Módulo | Medido frente al objetivo |
|---|---|
| coroutine | Fibra vs. hilo: de 16x a 28x más barata. Objetivo de 50x no cumplido |
| coroutine | Crear una tarea: 80 a 250 ns. Objetivo de 100 ns no cumplido de forma constante |
| resilience | Cadena de cuatro políticas: 101 a 123 ns. Objetivo de 50 ns no cumplido |
| cache | Lectura con acierto: 20.7 ns. Objetivo de 20 ns no cumplido |
| cache | Rendimiento de lectura de 1 a 8 hilos: 2x. Objetivo de 10x de 1 a 16 hilos no cumplido (4 núcleos físicos) |
| compression | Bloque LZ4, texto: comprime a 365 y 380 MB/s, frente a 391.2 MB/s de la referencia LZ4_compress_default en la misma máquina. Objetivo de 600 MB/s no cumplido. Descomprime a 3.24 GB/s en Windows y 2.48 GB/s en Linux (el objetivo de 3 GB/s solo se cumple en Windows) |
| compression | CRC32 (polinomio IEEE), tabla slice-by-8: 1.57 GB/s en Windows y 2.38 GB/s en Linux. Objetivo de 20 GB/s no cumplido: la instrucción x86 CRC32 solo calcula CRC32C, que sí lo alcanza |
| encoding | Validación UTF-8, texto mixto: 6.7 GB/s con AVX2. Objetivo de 15 GB/s no cumplido |
| config | Rendimiento del parser, archivo de 0.59 MB (MSVC 19.51, i7-6700): 133 MB/s. Objetivo de 200 MB/s no cumplido |
| storage | Lectura puntual aleatoria en una base de datos de 115 MB, mayor que la caché de la CPU: 831 a 1578 ns y 870 a 1176 ns. Objetivo de 1 µs no cumplido de forma robusta |
| regex | Frente a std::regex, 7 patrones sobre 2 MB: de 10x a 351x vs. libstdc++ en seis de los siete, de 1.3x a 42x vs. MSVC. Objetivo de 10x en todos no cumplido |
| regex | Compilar un patrón: de 1.0x a 2.2x la velocidad de std::regex en GCC, de 0.2x a 0.7x en MSVC. Objetivo de 10x más rápido no cumplido |
| rpc | Asignaciones por llamada: 1. Objetivo de cero no cumplido |
| bench | Repetibilidad en 10 ejecuciones: 0.4% a 14.1% y 1.3% a 14.1%. Objetivo de 2% no cumplido en esta máquina |
| math | Producto escalar y vectorial sobre puntos intercalados: 2.7x y de 1.9x a 2.2x, distancia intercalada 2.8x en MSVC. Objetivo de 3x a 4x no cumplido (las variantes en estructura de arrays llegan a entre 4.1x y 4.8x) |
| ecs | Iterar 1 millón con 3 componentes: 4.19 ms, en el techo del ancho de banda de memoria (14.3 GB/s). Objetivo de 1 ms no cumplido |
| Ml::Trees | Una predicción con 500 árboles: 12 a 14 µs con AVX2. Objetivo de 50 ns no cumplido (el suelo impuesto por la memoria es de 4 a 5 µs) |
| Ml::Trees | Verificación completa de un modelo de 100 MB: unos 13 ms. Objetivo de 5 ms no cumplido |
| Ml::Trees | Predicción por lotes: de 1.5x a 1.65x más rápida por fila que de una en una. Objetivo de 4x no cumplido |
| Ml::Trees | Modo compilado: 2.7x más lento que el intérprete AVX2. Objetivo de 2x más rápido no cumplido |
| Ml::Features | Un evento con 50 features: 0.45 µs con una entidad, 1.8 µs con 10,000. Objetivo de 100 ns no cumplido |
| Ml::Anomaly | Autoencoder: la feature que más contribuye es la responsable en el 94.3% de los casos. El objetivo del 95% fijado para los demás detectores no se cumple |
| ModelGuard | Verificar y descifrar 50 MB: unos 330 a 380 ms. Objetivo de 10 ms no cumplido |
| VectorIndex | Objetivo de 10,000 consultas/s con un recall del 95% sobre 1M x 768 no cumplido |
Mídelo en tu propia máquina.
El arnés de benchmarks viene con la biblioteca. Mide tu propia carga de trabajo durante la evaluación de 30 días.