迭代 131 - 性能优化 12¶
性能基准¶
总执行时间: 334.16 秒
测试通过: 478 passed
已优化函数(排除)¶
| 函数 | 迭代 | 优化内容 |
|——|——|———-|
| linebuffer.datetime() | 128 | 模块级常量,简化逻辑 |
| csvgeneric._loadline() | 128 | 缓存字段映射 |
| drawdown.next() | 127 | 缓存属性访问 |
| dateintern.num2date() | 127 | lru_cache |
| linebuffer.backwards() | 129 | 切片删除替代循环 |
| analyzer._notify_fund/cashvalue | 129 | 空 children 快速路径 |
| analyzer._dt_over/_get_dt_cmpkey | 130 | 缓存 timeframe 属性 |
| total_value.next() | 130 | 缓存 broker 引用 |
| bollinger.once() | 尝试失败 | 浮点精度问题 |
不可优化函数(核心/内置)¶
| 函数 | tottime | 原因 |
|——|———|——|
| lineseries.__setattr__() | 13.67s | 核心属性设置,高风险 |
| linebuffer.forward() | 11.18s | 核心数据推进 |
| linebuffer.__setitem__() | 8.53s | 核心数据写入 |
| linebuffer.__getitem__() | 7.41s | 核心数据读取 |
| builtins.len/setattr/getattr/hasattr | ~20s | Python 内置 |
| strategy._oncepost/_notify | ~12s | 策略核心逻辑 |
| linebuffer.set_idx/get_idx | ~8.5s | 核心索引操作 |
| linebuffer.advance() | 5.85s | 核心数据推进 |
剩余可优化函数分析¶
高优先级(tottime > 3s,有优化空间)¶
| 排名 | 函数 | tottime | 调用次数 | per_call | 优化可行性 |
|——|——|———|———-|———-|————|
| 1 | parameters.get() | 4.57s | 9.6M | 0.47μs | ⭐ 中 - 已有缓存,可尝试简化 |
| 2 | bbroker._get_value() | 4.27s | 711K | 6.00μs | ⭐ 中 - 缓存计算结果 |
| 3 | drawdown.next() | 4.26s | 687K | 6.19μs | ❌ 已优化 |
| 4 | csvgeneric._loadline() | 4.05s | 618K | 6.54μs | ❌ 已优化 |
| 5 | parameters.get_param() | 3.69s | 7.4M | 0.50μs | ⭐ 中 - 减少__getattribute__调用 |
| 6 | lineseries.__len__() | 3.16s | 7.3M | 0.43μs | ⭐ 低 - 已有缓存机制 |
中优先级(tottime 1-3s)¶
| 函数 | tottime | 调用次数 | 优化可行性 |
|——|———|———-|————|
| lineseries.__getattr__() | 2.69s | 1.7M | ⭐ 中 - 简化属性查找 |
| linebuffer.backwards() | 2.60s | 3.3M | ❌ 已优化 |
| autodict.__getattr__() | 1.93s | 5.7M | ⭐ 低 - 已最简 |
| analyzer._dt_over() | 1.85s | 1.3M | ❌ 已优化 |
| analyzer._get_dt_cmpkey() | 1.68s | 1.3M | ❌ 已优化 |
| lineiterator.__len__() | 1.68s | 4.0M | ⭐ 中 - 缓存长度 |
| total_value.next() | 1.23s | 522K | ❌ 已优化 |
优化计划¶
Phase 1: parameters 模块¶
1.1 parameters.get_param() 优化¶
问题*: 每次调用都执行
object.__getattribute__(self, "_param_manager")方案*: 在
__init__中缓存_param_manager引用
Phase 2: lineiterator 模块¶
2.1 lineiterator.__len__() 优化¶
问题*: 频繁计算长度
方案*: 缓存长度值
Phase 3: lineseries 模块¶
3.1 lineseries.__getattr__() 优化¶
问题*: 属性查找链较长
方案*: 简化常用属性的访问路径
实施记录¶
| 日期 | 优化项 | 状态 | 效果 |
|——|——–|——|——|
| 2026-01-17 | timereturn.notify_fund/on_dt_over - 缓存 p.data 引用 | ✅ 通过 | 减少 691K+次属性查找 |
| 2026-01-17 | metabase.p property - 使用__dict__.get() | ✅ 通过 | 减少 6M+次 getattr 调用 |
| 2026-01-17 | feed.advance_peek() - 缓存 float(‘inf’) | ✅ 通过 | 减少 1.49M+次对象创建 |
| 2026-01-17 | broker.getcommissioninfo() - 使用 getattr 替代 hasattr | ✅ 通过 | 减少 2.1M+次双重属性查找 |
| 2026-01-17 | order.getattr() - 使用 try/except 替代 hasattr | ✅ 通过 | 减少 1.65M+次双重属性查找 |
| 2026-01-17 | comminfo.profitandloss/cashadjust - 缓存 mult 参数 | ✅ 通过 | 减少 1.55M+次 get_param 调用 |