
Risultati misurati, non promesse di marketing. Tutti i benchmark eseguiti su Linux con GCC 13.3, 100.000 iterazioni, CPU pinnata.
Confronto diretto sulle operazioni FIX principali.
| Metrica | QuickFIX | NexusFIX | Miglioramento |
|---|---|---|---|
| Parse ExecutionReport | 730 ns | 246 ns | 3,0x più veloce |
| Parse NewOrderSingle | 661 ns | 229 ns | 2,9x più veloce |
| Accesso campi (4 campi) | 31 ns | 11 ns | 2,9x più veloce |
| Throughput | 1,19M msg/sec | 4,17M msg/sec | 3,5x superiore |
| Latenza P99 | 784 ns | 258 ns | 3,0x inferiore |
Come siamo passati da 730ns a 246ns in quattro fasi cumulative.
Sostituire le copie std::string con viste std::span<const char> nel buffer originale. Uno std::span è 16 byte nello stack — nessun heap, nessuna copia, nessun distruttore.
Sostituire std::map<int, std::string> con un array pre-indicizzato. L\'accesso ai campi diventa una singola istruzione mov indicizzata dal numero di tag FIX.
La scansione vettorizzata AVX2 dei delimitatori SOH elabora 32 byte per ciclo. ~13x più veloce della scansione byte per byte.
Tabelle di offset campi consteval e 22 tabelle di lookup a compile-time eliminano ~300 rami di runtime per la conversione enum/tipo.
Elaborazione di un messaggio NewOrderSingle sul percorso critico.
| Operazione | QuickFIX | NexusFIX |
|---|---|---|
| Allocazioni heap | ~12 (std::string, nodi std::map) | 0 |
| Archiviazione campi | Copie std::map<int, std::string> | Viste std::span nel buffer originale |
| Logica di parsing | Inserimento map a runtime | Tabella offset a compile-time |
| Impronta di memoria | Dinamica, imprevedibile | Statica, pool PMR pre-allocato |
| Overhead distruttore | ~12 distruttori std::string | 0 (nessuna memoria posseduta) |
Scelte di progettazione che si sommano per ottenere 3x di prestazioni.
| Tecnica | QuickFIX | NexusFIX |
|---|---|---|
| Memoria | Allocazione heap per messaggio | Viste std::span zero-copy |
| Lookup campi | O(log n) std::map | O(1) indicizzazione diretta su array |
| Parsing | Scansione byte per byte | AVX2 SIMD vettorizzato |
| Offset campi | Calcolo a runtime | consteval a compile-time |
| Conversione enum | Switch a runtime (~300 rami) | 22 tabelle di lookup a compile-time |
| Gestione errori | Eccezioni | std::expected (nessun throw) |
11 librerie leader del settore studiate. Cosa abbiamo imparato, cosa abbiamo costruito, cosa abbiamo misurato.
| Libreria | Cosa abbiamo imparato | Cosa abbiamo costruito | Risultato |
|---|---|---|---|
| hffix | Il lookup iteratore O(n) è subottimale per pacchetti FIX densi | Offset campi consteval + indicizzazione diretta O(1) | Accesso campi in 14ns |
| Abseil | Swiss Tables con sondaggio SIMD e fingerprint H2 | absl::flat_hash_map per lo store di sessione | Lookup 31% più veloci |
| Quill | Coda SPSC lock-free con formattazione differita | Quill come backend di logging | Latenza log mediana di 8ns |
| NanoLog | Codifica binaria + thread in background per logging a 7ns | DeferredProcessor<T> con serializzazione binaria statica | Riduzione dell\'84% (75→12ns) |
| liburing | DEFER_TASKRUN elimina i wakeup del kernel | io_uring + buffer registrati + multishot | I/O 7-27% più veloce |
| Highway | Astrazione SIMD portabile su set di istruzioni diversi | Mantenuti intrinsics calibrati manualmente per i pattern FIX | 13x di throughput |
| Seastar | Reactor share-nothing per I/O ad alta concorrenza | Core-pinning + pipelining lock-free | Miglioramento P99 dell\'8% |
| Folly | Fencing avanzato della memoria e primitive lock-free | Coda SPSC nativa + validazione con bit-masking | Zero dipendenze |
| Rigtorp | Il padding cache-line elimina il false sharing | SPSCQueue nativa con tecniche identiche | 88M ops/sec, 11ns |
| xsimd | Wrapper SIMD generici per operazioni matematiche | Intrinsics Intel diretti per la scansione SOH | 2x più veloce dei wrapper |
| Boost.PMR | Il buffer monotono abilita l\'allocazione arena per messaggio | std::pmr::monotonic_buffer_resource | Zero allocazioni heap |
Tre comandi per compilare ed eseguire i benchmark in autonomia.
git clone https://github.com/StratCraft/NexusFIX.git\ncd NexusFIX\n./start.sh build