StratCraft

Performance-Benchmarks

Gemessene Ergebnisse, keine Marketing-Behauptungen. Alle Benchmarks auf Linux mit GCC 13.3, 100.000 Iterationen, CPU-gebunden.

NexusFIX vs. QuickFIX

Direktvergleich der wichtigsten FIX-Operationen.

MetrikQuickFIXNexusFIXVerbesserung
ExecutionReport-Parsing730 ns246 ns3,0x schneller
NewOrderSingle-Parsing661 ns229 ns2,9x schneller
Feldzugriff (4 Felder)31 ns11 ns2,9x schneller
Durchsatz1,19M Msg/Sek.4,17M Msg/Sek.3,5x höher
P99-Latenz784 ns258 ns3,0x niedriger

Optimierungsreise

Von 730ns auf 246ns in vier aufeinander aufbauenden Phasen.

Phase 1: Zero-Copy-Parsing730ns → 520ns

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.

Phase 2: O(1)-Feldzugriff520ns → 380ns

std::map<int, std::string> durch ein vorindiziertes Array ersetzt. Feldzugriff wird zu einem einzigen mov-Befehl, indiziert durch die FIX-Tag-Nummer.

Phase 3: SIMD-Trennzeichen-Scanning380ns → 290ns

AVX2-vektorisiertes SOH-Trennzeichen-Scanning verarbeitet 32 Bytes pro Zyklus. ~13x schneller als Byte-für-Byte-Scanning.

Phase 4: Compile-Time-Offsets290ns → 246ns

consteval-Feld-Offset-Tabellen und 22 Compile-Time-Lookup-Tabellen eliminieren ~300 Laufzeit-Branches für Enum-/Typ-Konvertierung.

Null-Allokations-Nachweis

Verarbeitung einer NewOrderSingle-Nachricht auf dem Hot Path.

OperationQuickFIXNexusFIX
Heap-Allokationen~12 (std::string, std::map-Knoten)0
Feldspeicherungstd::map<int, std::string>-Kopienstd::span-Ansichten in den Originalpuffer
Parsing-LogikLaufzeit-Map-EinfügungCompile-Time-Offset-Tabelle
Speicher-FootprintDynamisch, unvorhersehbarStatisch, vorab allozierter PMR-Pool
Destruktor-Overhead~12 std::string-Destruktoren0 (kein eigener Speicher)

Technikvergleich

Designentscheidungen, die sich zu 3x Performance summieren.

TechnikQuickFIXNexusFIX
SpeicherHeap-Allokation pro NachrichtZero-Copy-std::span-Ansichten
FeldzugriffO(log n) std::mapO(1) direktes Array-Indexing
ParsingByte-für-Byte-ScanningAVX2 SIMD vektorisiert
Feld-OffsetsLaufzeitberechnungconsteval Compile-Time
Enum-KonvertierungLaufzeit-Switch (~300 Branches)22 Compile-Time-Lookup-Tabellen
FehlerbehandlungAusnahmenstd::expected (kein Throw)

Architektur-Einflüsse

11 führende Bibliotheken untersucht. Was wir gelernt, gebaut und gemessen haben.

BibliothekWas wir gelernt habenWas wir gebaut habenErgebnis
hffixO(n)-Iterator-Lookup ist für dichte FIX-Pakete suboptimalconsteval-Feld-Offsets + O(1)-Direktindizierung14ns Feldzugriff
AbseilSwiss Tables mit SIMD-Probing und H2-Fingerprintsabsl::flat_hash_map für Session-Store31% schnellere Lookups
QuillLock-free SPSC-Queue mit verzögerter FormatierungQuill als Logging-Backend8ns mediane Log-Latenz
NanoLogBinäre Kodierung + Hintergrund-Thread für 7ns LoggingDeferredProcessor<T> mit statischer Binär-Serialisierung84% Reduktion (75→12ns)
liburingDEFER_TASKRUN eliminiert Kernel-Task-Aufweckungenio_uring + registrierte Puffer + Multishot7-27% schnelleres I/O
HighwayPortable SIMD-Abstraktion über Befehlssätze hinwegHandoptimierte Intrinsics für FIX-Muster beibehalten13x Durchsatz
SeastarShare-nothing-Reaktor für hochgradig paralleles I/OCore-Pinning + Lock-free-Pipelining8% P99-Verbesserung
FollyFortgeschrittenes Memory-Fencing und Lock-free-PrimitiveNatives SPSC-Queue + Bit-Masking-ValidierungNull Abhängigkeit
RigtorpCache-Line-Padding eliminiert False SharingNatives SPSCQueue mit identischen Techniken88M ops/sec, 11ns
xsimdGenerische SIMD-Wrapper für mathematische OperationenDirekte Intel-Intrinsics für SOH-Scanning2x schneller als Wrapper
Boost.PMRMonotonischer Puffer ermöglicht Arena-Allokation pro Nachrichtstd::pmr::monotonic_buffer_resourceNull Heap-Allokation

Bereit, NexusFIX auszuprobieren?

Drei Befehle zum Bauen und Ausführen der Benchmarks.

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