StratCraft

Benchmark di prestazione

Risultati misurati, non promesse di marketing. Tutti i benchmark eseguiti su Linux con GCC 13.3, 100.000 iterazioni, CPU pinnata.

NexusFIX vs QuickFIX

Confronto diretto sulle operazioni FIX principali.

MetricaQuickFIXNexusFIXMiglioramento
Parse ExecutionReport730 ns246 ns3,0x più veloce
Parse NewOrderSingle661 ns229 ns2,9x più veloce
Accesso campi (4 campi)31 ns11 ns2,9x più veloce
Throughput1,19M msg/sec4,17M msg/sec3,5x superiore
Latenza P99784 ns258 ns3,0x inferiore

Percorso di ottimizzazione

Come siamo passati da 730ns a 246ns in quattro fasi cumulative.

Fase 1: Parsing Zero-Copy730ns → 520ns

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.

Fase 2: Lookup campi O(1)520ns → 380ns

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.

Fase 3: Scansione delimitatori SIMD380ns → 290ns

La scansione vettorizzata AVX2 dei delimitatori SOH elabora 32 byte per ciclo. ~13x più veloce della scansione byte per byte.

Fase 4: Offset a compile-time290ns → 246ns

Tabelle di offset campi consteval e 22 tabelle di lookup a compile-time eliminano ~300 rami di runtime per la conversione enum/tipo.

Prova di zero allocazioni

Elaborazione di un messaggio NewOrderSingle sul percorso critico.

OperazioneQuickFIXNexusFIX
Allocazioni heap~12 (std::string, nodi std::map)0
Archiviazione campiCopie std::map<int, std::string>Viste std::span nel buffer originale
Logica di parsingInserimento map a runtimeTabella offset a compile-time
Impronta di memoriaDinamica, imprevedibileStatica, pool PMR pre-allocato
Overhead distruttore~12 distruttori std::string0 (nessuna memoria posseduta)

Confronto tecnico

Scelte di progettazione che si sommano per ottenere 3x di prestazioni.

TecnicaQuickFIXNexusFIX
MemoriaAllocazione heap per messaggioViste std::span zero-copy
Lookup campiO(log n) std::mapO(1) indicizzazione diretta su array
ParsingScansione byte per byteAVX2 SIMD vettorizzato
Offset campiCalcolo a runtimeconsteval a compile-time
Conversione enumSwitch a runtime (~300 rami)22 tabelle di lookup a compile-time
Gestione erroriEccezionistd::expected (nessun throw)

Influenze architetturali

11 librerie leader del settore studiate. Cosa abbiamo imparato, cosa abbiamo costruito, cosa abbiamo misurato.

LibreriaCosa abbiamo imparatoCosa abbiamo costruitoRisultato
hffixIl lookup iteratore O(n) è subottimale per pacchetti FIX densiOffset campi consteval + indicizzazione diretta O(1)Accesso campi in 14ns
AbseilSwiss Tables con sondaggio SIMD e fingerprint H2absl::flat_hash_map per lo store di sessioneLookup 31% più veloci
QuillCoda SPSC lock-free con formattazione differitaQuill come backend di loggingLatenza log mediana di 8ns
NanoLogCodifica binaria + thread in background per logging a 7nsDeferredProcessor<T> con serializzazione binaria staticaRiduzione dell\'84% (75→12ns)
liburingDEFER_TASKRUN elimina i wakeup del kernelio_uring + buffer registrati + multishotI/O 7-27% più veloce
HighwayAstrazione SIMD portabile su set di istruzioni diversiMantenuti intrinsics calibrati manualmente per i pattern FIX13x di throughput
SeastarReactor share-nothing per I/O ad alta concorrenzaCore-pinning + pipelining lock-freeMiglioramento P99 dell\'8%
FollyFencing avanzato della memoria e primitive lock-freeCoda SPSC nativa + validazione con bit-maskingZero dipendenze
RigtorpIl padding cache-line elimina il false sharingSPSCQueue nativa con tecniche identiche88M ops/sec, 11ns
xsimdWrapper SIMD generici per operazioni matematicheIntrinsics Intel diretti per la scansione SOH2x più veloce dei wrapper
Boost.PMRIl buffer monotono abilita l\'allocazione arena per messaggiostd::pmr::monotonic_buffer_resourceZero allocazioni heap

Pronto a provare NexusFIX?

Tre comandi per compilare ed eseguire i benchmark in autonomia.

git clone https://github.com/StratCraft/NexusFIX.git\ncd NexusFIX\n./start.sh build