StratCraft

Benchmarks de Desempenho

Resultados medidos, não declarações de marketing. Todos os benchmarks executados no Linux com GCC 13.3, 100.000 iterações, CPU fixada.

NexusFIX vs QuickFIX

Comparação direta nas operações FIX principais.

MétricaQuickFIXNexusFIXMelhoria
Parse de ExecutionReport730 ns246 ns3,0x mais rápido
Parse de NewOrderSingle661 ns229 ns2,9x mais rápido
Acesso a campos (4 campos)31 ns11 ns2,9x mais rápido
Throughput1,19M msg/seg4,17M msg/seg3,5x maior
Latência P99784 ns258 ns3,0x menor

Percurso de otimização

Como passámos de 730ns para 246ns em quatro fases compostas.

Fase 1: Parsing sem cópia730ns → 520ns

Substituir cópias de std::string por vistas std::span<const char> no buffer original. Um std::span tem 16 bytes na pilha — sem heap, sem cópia, sem destrutor.

Fase 2: Acesso a campos O(1)520ns → 380ns

Substituir std::map<int, std::string> por um array pré-indexado. O acesso a campos torna-se uma única instrução mov indexada pelo número de tag FIX.

Fase 3: Scanning de delimitadores SIMD380ns → 290ns

O scanning vetorizado AVX2 de delimitadores SOH processa 32 bytes por ciclo. ~13x mais rápido do que o scanning byte a byte.

Fase 4: Offsets em tempo de compilação290ns → 246ns

Tabelas de offset consteval e 22 tabelas de lookup em tempo de compilação eliminam ~300 ramos em tempo de execução para conversão enum/tipo.

Prova de alocação zero

Processamento de uma mensagem NewOrderSingle no hot path.

OperaçãoQuickFIXNexusFIX
Alocações de heap~12 (std::string, nós std::map)0
Armazenamento de camposCópias std::map<int, std::string>Vistas std::span no buffer original
Lógica de parsingInserção em map em tempo de execuçãoTabela de offset em tempo de compilação
Footprint de memóriaDinâmico, imprevisívelEstático, pool PMR pré-alocado
Sobrecarga de destrutor~12 destrutores std::string0 (sem memória própria)

Comparação de técnicas

Decisões de design que se compõem para um desempenho 3x.

TécnicaQuickFIXNexusFIX
MemóriaAlocação de heap por mensagemVistas std::span sem cópia
Acesso a camposO(log n) std::mapO(1) indexação direta de array
ParsingScanning byte a byteAVX2 SIMD vetorizado
Offsets de camposCálculo em tempo de execuçãoconsteval em tempo de compilação
Conversão de enumSwitch em tempo de execução (~300 ramos)22 tabelas de lookup em tempo de compilação
Tratamento de errosExceçõesstd::expected (sem throw)

Influências arquitetónicas

11 bibliotecas líderes da indústria estudadas. O que aprendemos, o que construímos, o que medimos.

BibliotecaO que aprendemosO que construímosResultado
hffixA pesquisa O(n) por iterador é subótima para pacotes FIX densosOffsets consteval + indexação O(1) diretaAcesso a campos em 14ns
AbseilSwiss Tables com sondagem SIMD e fingerprints H2absl::flat_hash_map para armazenamento de sessão31% de lookups mais rápidos
QuillFila SPSC lock-free com formatação diferidaQuill como backend de loggingLatência mediana de log de 8ns
NanoLogCodificação binária + thread de fundo para logging de 7nsDeferredProcessor<T> com serialização binária estáticaRedução de 84% (75→12ns)
liburingDEFER_TASKRUN elimina wakeups de tarefas do kernelio_uring + buffers registados + multishotI/O 7-27% mais rápido
HighwayAbstração SIMD portátil entre conjuntos de instruçõesMantivemos intrínsecos ajustados manualmente para padrões FIXThroughput 13x
SeastarReator share-nothing para I/O de alta concorrênciaCore-pinning + pipelining lock-freeMelhoria de 8% no P99
FollyFencing de memória avançada e primitivas lock-freeFila SPSC nativa + validação por bit-maskingZero dependência
RigtorpPreenchimento de cache-line elimina falso compartilhamentoSPSCQueue nativa com técnicas idênticas88M ops/seg, 11ns
xsimdWrappers SIMD genéricos para operações matemáticasIntrínsecos Intel diretos para scanning SOH2x mais rápido do que wrappers
Boost.PMRBuffer monotónico permite alocação em arena por mensagemstd::pmr::monotonic_buffer_resourceZero alocação de heap

Pronto para experimentar o NexusFIX?

Três comandos para compilar e executar os benchmarks você mesmo.

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