
Gemessene Ergebnisse, keine Marketing-Behauptungen. Alle Benchmarks auf Linux mit GCC 13.3, 100.000 Iterationen, CPU-gebunden.
Direktvergleich der wichtigsten FIX-Operationen.
| Metrik | QuickFIX | NexusFIX | Verbesserung |
|---|---|---|---|
| ExecutionReport-Parsing | 730 ns | 246 ns | 3,0x schneller |
| NewOrderSingle-Parsing | 661 ns | 229 ns | 2,9x schneller |
| Feldzugriff (4 Felder) | 31 ns | 11 ns | 2,9x schneller |
| Durchsatz | 1,19M Msg/Sek. | 4,17M Msg/Sek. | 3,5x höher |
| P99-Latenz | 784 ns | 258 ns | 3,0x niedriger |
Von 730ns auf 246ns in vier aufeinander aufbauenden Phasen.
std::string-Kopien durch std::span<const char>-Ansichten in den Originalpuffer ersetzt. Ein std::span ist 16 Bytes auf dem Stack — kein Heap, keine Kopie, kein Destruktor.
std::map<int, std::string> durch ein vorindiziertes Array ersetzt. Feldzugriff wird zu einem einzigen mov-Befehl, indiziert durch die FIX-Tag-Nummer.
AVX2-vektorisiertes SOH-Trennzeichen-Scanning verarbeitet 32 Bytes pro Zyklus. ~13x schneller als Byte-für-Byte-Scanning.
consteval-Feld-Offset-Tabellen und 22 Compile-Time-Lookup-Tabellen eliminieren ~300 Laufzeit-Branches für Enum-/Typ-Konvertierung.
Verarbeitung einer NewOrderSingle-Nachricht auf dem Hot Path.
| Operation | QuickFIX | NexusFIX |
|---|---|---|
| Heap-Allokationen | ~12 (std::string, std::map-Knoten) | 0 |
| Feldspeicherung | std::map<int, std::string>-Kopien | std::span-Ansichten in den Originalpuffer |
| Parsing-Logik | Laufzeit-Map-Einfügung | Compile-Time-Offset-Tabelle |
| Speicher-Footprint | Dynamisch, unvorhersehbar | Statisch, vorab allozierter PMR-Pool |
| Destruktor-Overhead | ~12 std::string-Destruktoren | 0 (kein eigener Speicher) |
Designentscheidungen, die sich zu 3x Performance summieren.
| Technik | QuickFIX | NexusFIX |
|---|---|---|
| Speicher | Heap-Allokation pro Nachricht | Zero-Copy-std::span-Ansichten |
| Feldzugriff | O(log n) std::map | O(1) direktes Array-Indexing |
| Parsing | Byte-für-Byte-Scanning | AVX2 SIMD vektorisiert |
| Feld-Offsets | Laufzeitberechnung | consteval Compile-Time |
| Enum-Konvertierung | Laufzeit-Switch (~300 Branches) | 22 Compile-Time-Lookup-Tabellen |
| Fehlerbehandlung | Ausnahmen | std::expected (kein Throw) |
11 führende Bibliotheken untersucht. Was wir gelernt, gebaut und gemessen haben.
| Bibliothek | Was wir gelernt haben | Was wir gebaut haben | Ergebnis |
|---|---|---|---|
| hffix | O(n)-Iterator-Lookup ist für dichte FIX-Pakete suboptimal | consteval-Feld-Offsets + O(1)-Direktindizierung | 14ns Feldzugriff |
| Abseil | Swiss Tables mit SIMD-Probing und H2-Fingerprints | absl::flat_hash_map für Session-Store | 31% schnellere Lookups |
| Quill | Lock-free SPSC-Queue mit verzögerter Formatierung | Quill als Logging-Backend | 8ns mediane Log-Latenz |
| NanoLog | Binäre Kodierung + Hintergrund-Thread für 7ns Logging | DeferredProcessor<T> mit statischer Binär-Serialisierung | 84% Reduktion (75→12ns) |
| liburing | DEFER_TASKRUN eliminiert Kernel-Task-Aufweckungen | io_uring + registrierte Puffer + Multishot | 7-27% schnelleres I/O |
| Highway | Portable SIMD-Abstraktion über Befehlssätze hinweg | Handoptimierte Intrinsics für FIX-Muster beibehalten | 13x Durchsatz |
| Seastar | Share-nothing-Reaktor für hochgradig paralleles I/O | Core-Pinning + Lock-free-Pipelining | 8% P99-Verbesserung |
| Folly | Fortgeschrittenes Memory-Fencing und Lock-free-Primitive | Natives SPSC-Queue + Bit-Masking-Validierung | Null Abhängigkeit |
| Rigtorp | Cache-Line-Padding eliminiert False Sharing | Natives SPSCQueue mit identischen Techniken | 88M ops/sec, 11ns |
| xsimd | Generische SIMD-Wrapper für mathematische Operationen | Direkte Intel-Intrinsics für SOH-Scanning | 2x schneller als Wrapper |
| Boost.PMR | Monotonischer Puffer ermöglicht Arena-Allokation pro Nachricht | std::pmr::monotonic_buffer_resource | Null Heap-Allokation |
Drei Befehle zum Bauen und Ausführen der Benchmarks.
git clone https://github.com/StratCraft/NexusFIX.git\ncd NexusFIX\n./start.sh build