
Resultados medidos, no afirmaciones de marketing. Todos los benchmarks ejecutados en Linux con GCC 13.3, 100 000 iteraciones, CPU anclada.
Comparación directa en las operaciones FIX fundamentales.
| Métrica | QuickFIX | NexusFIX | Mejora |
|---|---|---|---|
| Parsing de ExecutionReport | 730 ns | 246 ns | 3,0x más rápido |
| Parsing de NewOrderSingle | 661 ns | 229 ns | 2,9x más rápido |
| Acceso a campos (4 campos) | 31 ns | 11 ns | 2,9x más rápido |
| Rendimiento | 1,19M msg/seg | 4,17M msg/seg | 3,5x mayor |
| Latencia P99 | 784 ns | 258 ns | 3,0x menor |
Cómo pasamos de 730ns a 246ns en cuatro fases acumulativas.
Sustituir copias de std::string por vistas std::span<const char> sobre el buffer original. Un std::span ocupa 16 bytes en la pila — sin heap, sin copia, sin destructor.
Sustituir std::map<int, std::string> por un array pre-indexado. El acceso a campos se convierte en una sola instrucción mov indexada por número de tag FIX.
Exploración vectorizada AVX2 de delimitadores SOH que procesa 32 bytes por ciclo. ~13x más rápido que el escaneo byte a byte.
Tablas de offsets de campos consteval y 22 tablas de búsqueda en tiempo de compilación eliminan ~300 ramas en tiempo de ejecución para conversión de enums/tipos.
Procesando un mensaje NewOrderSingle en la ruta crítica.
| Operación | QuickFIX | NexusFIX |
|---|---|---|
| Asignaciones en heap | ~12 (std::string, nodos std::map) | 0 |
| Almacenamiento de campos | Copias std::map<int, std::string> | Vistas std::span sobre el buffer original |
| Lógica de parsing | Inserción en mapa en tiempo de ejecución | Tabla de offsets en tiempo de compilación |
| Huella de memoria | Dinámica, impredecible | Estática, pool PMR preasignado |
| Sobrecarga de destructor | ~12 destructores std::string | 0 (sin memoria propia) |
Decisiones de diseño que se acumulan para dar 3x de rendimiento.
| Técnica | QuickFIX | NexusFIX |
|---|---|---|
| Memoria | Asignación en heap por mensaje | Vistas std::span de copia cero |
| Búsqueda de campo | O(log n) std::map | O(1) indexación directa de array |
| Parsing | Escaneo byte a byte | Vectorizado AVX2 SIMD |
| Offsets de campo | Cálculo en tiempo de ejecución | consteval en tiempo de compilación |
| Conversión de enums | switch en tiempo de ejecución (~300 ramas) | 22 tablas de búsqueda en tiempo de compilación |
| Manejo de errores | Excepciones | std::expected (sin lanzamiento) |
11 librerías líderes del sector estudiadas. Lo que aprendimos, lo que construimos, lo que medimos.
| Librería | Lo que aprendimos | Lo que construimos | Resultado |
|---|---|---|---|
| hffix | La búsqueda O(n) con iterador es subóptima para paquetes FIX densos | Offsets de campo consteval + indexación directa O(1) | Acceso a campo en 14ns |
| Abseil | Swiss Tables con sondeo SIMD y huellas H2 | absl::flat_hash_map para el almacén de sesiones | Búsquedas un 31% más rápidas |
| Quill | Cola SPSC sin bloqueo con formateo diferido | Quill como backend de logging | Latencia de log mediana de 8ns |
| NanoLog | Codificación binaria + hilo en segundo plano para logging de 7ns | DeferredProcessor<T> con serialización binaria estática | Reducción del 84% (75→12ns) |
| liburing | DEFER_TASKRUN elimina las activaciones de tareas del kernel | io_uring + buffers registrados + multishot | I/O un 7-27% más rápido |
| Highway | Abstracción SIMD portable entre conjuntos de instrucciones | Se mantuvieron intrínsecos ajustados a mano para patrones FIX | 13x de rendimiento |
| Seastar | Reactor share-nothing para I/O de alta concurrencia | Anclaje de núcleo + pipelining sin bloqueo | Mejora del 8% en P99 |
| Folly | Vallas de memoria avanzadas y primitivas sin bloqueo | Cola SPSC nativa + validación con bit-masking | Sin dependencia externa |
| Rigtorp | El relleno de línea de caché elimina el false sharing | SPSCQueue nativa con técnicas idénticas | 88M ops/seg, 11ns |
| xsimd | Wrappers SIMD genéricos para operaciones matemáticas | Intrínsecos Intel directos para escaneo SOH | 2x más rápido que los wrappers |
| Boost.PMR | El buffer monotónico habilita la asignación en arena por mensaje | std::pmr::monotonic_buffer_resource | Cero asignaciones en heap |
Tres comandos para compilar y ejecutar los benchmarks usted mismo.
git clone https://github.com/StratCraft/NexusFIX.git\ncd NexusFIX\n./start.sh build