StratCraft

性能基准测试

实测结果,非营销宣传。所有基准测试在 Linux 上运行,GCC 13.3,100,000 次迭代,CPU 固定。

NexusFIX vs QuickFIX

核心 FIX 操作的正面对比。

指标QuickFIXNexusFIX提升
ExecutionReport 解析730 ns246 ns快 3.0 倍
NewOrderSingle 解析661 ns229 ns快 2.9 倍
字段访问(4 个字段)31 ns11 ns快 2.9 倍
吞吐量1.19M 消息/秒4.17M 消息/秒高 3.5 倍
P99 延迟784 ns258 ns低 3.0 倍

优化历程

我们如何通过四个复合阶段从 730ns 优化到 246ns。

阶段 1:零拷贝解析730ns → 520ns

用 std::span<const char> 视图替代 std::string 拷贝,直接引用原始缓冲区。std::span 在栈上仅 16 字节——无堆分配、无拷贝、无析构。

阶段 2:O(1) 字段查找520ns → 380ns

用预索引数组替代 std::map<int, std::string>。字段访问变为一条 mov 指令,按 FIX 标签号索引。

阶段 3:SIMD 分隔符扫描380ns → 290ns

AVX2 向量化 SOH 分隔符扫描,每周期处理 32 字节。比逐字节扫描快约 13 倍。

阶段 4:编译期偏移量290ns → 246ns

consteval 字段偏移表和 22 个编译期查找表消除了约 300 个运行时分支用于枚举/类型转换。

零分配证明

在热路径上处理 NewOrderSingle 消息。

操作QuickFIXNexusFIX
堆分配约 12 次(std::string、std::map 节点)0
字段存储std::map<int, std::string> 拷贝std::span 视图引用原始缓冲区
解析逻辑运行时 map 插入编译期偏移表
内存占用动态,不可预测静态,预分配 PMR 池
析构开销约 12 个 std::string 析构0(无拥有内存)

技术对比

复合产生 3 倍性能的设计决策。

技术QuickFIXNexusFIX
内存每消息堆分配零拷贝 std::span 视图
字段查找O(log n) std::mapO(1) 直接数组索引
解析逐字节扫描AVX2 SIMD 向量化
字段偏移运行时计算consteval 编译期
枚举转换运行时 switch(约 300 个分支)22 个编译期查找表
错误处理异常std::expected(无 throw)

架构影响

研究了 11 个行业领先的库。我们学到了什么,构建了什么,测量了什么。

学到了什么构建了什么结果
hffixO(n) 迭代器查找对密集 FIX 数据包不够优化consteval 字段偏移 + O(1) 直接索引14ns 字段访问
Abseil使用 SIMD 探测和 H2 指纹的 Swiss Tablesabsl::flat_hash_map 用于会话存储查找速度提升 31%
Quill无锁 SPSC 队列与延迟格式化Quill 作为日志后端8ns 中位数日志延迟
NanoLog二进制编码 + 后台线程实现 7ns 日志DeferredProcessor<T> 静态二进制序列化减少 84%(75→12ns)
liburingDEFER_TASKRUN 消除内核任务唤醒io_uring + 注册缓冲区 + 多次接收I/O 快 7-27%
Highway跨指令集的可移植 SIMD 抽象保留手动调优的 FIX 模式内联函数吞吐量提升 13 倍
Seastar无共享反应器用于高并发 I/OCPU 核心绑定 + 无锁流水线P99 改善 8%
Folly高级内存栅栏和无锁原语原生 SPSC 队列 + 位掩码验证零外部依赖
Rigtorp缓存行填充消除伪共享使用相同技术的原生 SPSCQueue88M ops/sec,11ns
xsimd通用 SIMD 包装器用于数学运算直接 Intel 内联函数用于 SOH 扫描比包装器快 2 倍
Boost.PMR单调缓冲区实现每消息 Arena 分配std::pmr::monotonic_buffer_resource零堆分配

准备试用 NexusFIX?

三条命令即可构建并运行基准测试。

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