第一章:Python性能优化基石

做量化交易这些年,我见过太多人把Python用成了“慢速语言”。其实不是Python慢,是你没选对工具。今天咱们就从数据结构选型开始,聊聊性能优化的那些坑。

1.1 数据结构选型:选对了,性能翻倍

我个人习惯,写任何代码前先想清楚数据长什么样。量化交易里,数据无非几种:时间序列、订单簿、持仓信息。每种数据都有最适合它的容器。

数据结构 适用场景 时间复杂度
列表(list) 有序数据,频繁追加 O(1)追加,O(n)查找
字典(dict) 键值对,快速查找 O(1)平均查找
集合(set) 去重、成员判断 O(1)平均查找
元组(tuple) 不可变数据,哈希键 O(1)索引

举个例子。我在项目中处理过百万级的订单数据,如果用列表存订单ID,每次查找都要遍历——那速度,简直让人崩溃。换成字典后,查找时间从秒级降到了毫秒级。

核心原则:查找用字典,去重用集合,有序用列表,固定用元组。

1.2 列表与字典的性能陷阱

列表和字典,看着简单,用起来全是坑。我踩过的坑,今天一次性说清楚。

列表的陷阱

列表的insert(0, item)操作,时间复杂度是O(n)。为什么?因为插入到头部,所有元素都得往后挪。我曾经在循环里这么干过,处理10万条数据,跑了整整两分钟。

# 错误示范
data = []
for i in range(100000):
    data.insert(0, i)  # O(n)操作,慢到怀疑人生

# 正确做法
data = []
for i in range(100000):
    data.append(i)  # O(1)操作
data.reverse()  # 最后反转一次,O(n)

避坑指南:我曾经在实时行情处理中,用列表做队列。结果延迟越来越高,最后发现是pop(0)导致的。换成collections.deque后,问题迎刃而解。

字典的陷阱

字典的键必须是可哈希的。什么意思?就是键不能是列表、字典这种可变类型。我见过有人用列表当键,直接报TypeError

还有个坑:字典的in操作是O(1),但如果你用keys()方法,它会返回一个视图对象,性能没问题。但如果你用list(dict.keys()),那就变成O(n)了。

# 高效写法
if key in my_dict:  # O(1)
    value = my_dict[key]

# 低效写法
if key in list(my_dict.keys()):  # O(n),多此一举
    value = my_dict[key]

1.3 内置函数与标准库:Python的隐藏武器

Python内置函数和标准库,说白了就是官方给你写好的高性能代码。你想想看,这些函数底层都是C语言实现的,比你手写的Python循环快一个数量级。

常用内置函数

  • map():批量处理,比列表推导式快
  • filter():条件过滤,避免手动循环
  • zip():并行迭代,代码更简洁
  • sorted():排序,底层是Timsort算法
# 用map替代循环
prices = [100.5, 101.2, 99.8]
# 低效
new_prices = []
for p in prices:
    new_prices.append(p * 1.01)

# 高效
new_prices = list(map(lambda x: x * 1.01, prices))

标准库的威力

我建议你多看看collectionsitertoolsfunctools这几个模块。它们能解决很多常见问题。

模块 常用工具 用途
collections deque, Counter, defaultdict 队列、计数、默认字典
itertools chain, groupby, product 迭代器操作、分组、笛卡尔积
functools lru_cache, partial 缓存、偏函数

个人经验:我在做回测系统时,用functools.lru_cache缓存计算结果,速度提升了3倍。你想想看,同样的计算重复执行,缓存一下多划算。

1.4 知识体系总览

下面这张图,是我整理的本章节知识体系。你可以把它当成一张地图,随时回来看看。

Python性能优化基石 数据结构选型 性能陷阱 内置函数与标准库 列表:有序、追加 字典:键值、查找 集合:去重、成员判断 元组:不可变、哈希 insert(0) O(n) pop(0) O(n) 字典键不可变 keys()转列表 O(n) map():批量处理 filter():条件过滤 collections:deque等 functools:lru_cache 核心原则:选对结构 + 避开陷阱 + 善用内置 = 高性能Python 量化交易中,每毫秒都很宝贵

嗯,这张图把本章的核心内容都串起来了。你写代码时,可以对照着看看自己有没有走弯路。

最后说一句:性能优化不是一蹴而就的事。我建议你先写出能跑的代码,再用工具(比如timeit模块)测一下瓶颈在哪。别一开始就想着优化,那样反而容易过度设计。

专注资料整理