组合执行性能分析记录
语言:简体中文 · English
预注册方法
本轮性能分析只使用确定性合成输入,不读取生产数据。记录基线和性能剖析结果前,不会选择 Rust 内核。
每种工作负载运行 scripts/benchmarks/portfolio_execution_profile.py,计时重复五次。固定样本包含 120 个工作日、120 只证券、四次调仓共 320 条目标记录、确定性价格和流动性(amount = 200000 + (symbol_index % 13) * 175,medadv20_amount = 400000 + (symbol_index % 13) * 350),以及明确的市场规则列。该流动性范围允许 100 股整手成交,同时保留多日部分成交。脚本报告工作负载维度、输出表大小、规范化结果表的 SHA-256 摘要、中位耗时、进程峰值 RSS、软件版本及 Python profile 累计样本。Linux 的 ru_maxrss 以 KiB 报告。
工作负载包括:
daily-ledger:包含订单、成交、每日现金与持仓、整手、T+1、涨跌停和上市状态字段的执行调整 NAV。order-matching:按容量规划调仓订单,包含每日流动性上限、部分成交以及撤单和截止期限路径。scenario-sweep:按四个参与率和三个买入截止日执行十二次容量回测,摘要覆盖全部输出。
完成基线运行后,记录运行环境和确切输出摘要。只有在剖析中发现稳定的数组计算内核,且主导工作负载的重复端到端中位耗时有望至少提升 2 倍时,才考虑 Rust 内核。Python 路径继续作为参考实现和必需回退。候选实现必须先通过一致性测试,随后重复基准也达到同一门槛。
基线结果
运行环境:Linux 6.18.52-1-lts、x86_64、Intel Core i5-4690K 3.50 GHz、4 个逻辑处理器、31 GiB 内存、Python 3.13.14、NumPy 2.2.6 和 pandas 3.0.5。剖析在仓库锁定的 uv 环境中运行。输入与生成结果均保存在仓库之外。
| 工作负载 | 维度与输出 | 中位耗时 | 峰值 RSS | 输出 SHA-256 |
|---|---|---|---|---|
daily-ledger |
14,400 条价格、320 个持仓、119 条日度记录、352 张订单、1,831 笔成交 | 2.699452 s | 207,752 KiB | 0ee0f9d7d3d5f74aabecc571dac9b1cf2b728ac73f562f02f79231de5469133c |
order-matching |
14,400 条价格、320 个持仓、352 张订单、1,837 笔成交 | 0.382356 s | 199,628 KiB | 1778a72f9feae297d6b6b200d48a505521610e332af7380f338c7a70fa1b0380 |
scenario-sweep |
12 组配置、共 3,636 张订单、19,269 笔成交 | 4.040868 s | 206,864 KiB | 6216141b4dce65d54de9b1930f7346545c6b8e11b5259d903b3a8617c985d1df |
每个中位数都来自五次计时重复。每次重复都得到相同的结果摘要和数据表清单。脚本还会额外运行一次 cProfile。这些插桩耗时只用于比较调用栈占比,不计入实际耗时中位数。
每日账本样本中,Python 自身耗时最高的函数是 execution_sim/capacity.py::_table_float_at,47,344 次调用共耗时 0.267 秒。Pandas 的 DatetimeIndex.get_loc 耗时 0.253 秒,共调用 102,593 次。订单匹配和参数扫描的剖析也显示相同的标量查找开销族,_table_float_at 分别耗时 0.035 秒和 0.349 秒。耗时分散在 Pandas 标量索引、日期查找、容量检查和有状态订单处理中,没有单一数组计算内核主导端到端运行。
决定
本阶段不增加 Rust 内核。性能剖析没有发现一个独立数值内核能够可信地达到预注册的端到端中位耗时两倍提升目标。主要开销来自反复的标量 DataFrame/日期查找,以及交错进行的订单和现金状态决策。把这一路径迁移到 Rust,就需要整体迁移订单生命周期与账本状态,已经超出单个窄内核的范围。Python 实现仍是必需的参考实现。保留本基准与精确结果摘要,供之后更大范围的数据布局优化对照。