人人都会AI编程

26.2 代码级优化技巧

更新时间:2026-07-12

性能优化不是从改算法开始的,往往先从写好每一行代码入手。Python 里,一些小小的调整就能让程序运行快上几倍。下面这些技巧都是生产环境验证过的,实用且易于落地。

优先使用内置函数和标准库

Python 的内置函数和标准库大多是用 C 实现的,执行速度远快于你自己用纯 Python 写的循环。

  • sum() 别自己写循环

想对一个列表求和,写 for 循环不仅代码长,也更慢:

  # 自己写循环,慢
  total = 0
  for x in data:
      total += x

  # 内置 sum,快几倍
  total = sum(data)
  
  • map()filter() 和列表推导式

它们底层走 C 循环,比显式的 for 循环快。

  # 慢
  result = []
  for item in items:
      result.append(func(item))

  # 快:列表推导
  result = [func(item) for item in items]

  # 也快:map
  result = list(map(func, items))
  
  • 善用 collectionsitertoolsfunctools

比如 Counter 统计词频、deque 实现高效队列、lru_cache 缓存重复计算,都是标准库里的性能利器。

减少循环层级与循环内操作

循环是 Python 里最耗时的结构之一,循环层数一多,耗时就以乘积级增长。

  • 将不变的运算提到循环外

不要在循环里重复计算或访问不变量。

  # 不好:每次循环都算 len(data)
  for i in range(len(data)):
      process(data[i])

  # 好
  n = len(data)
  for i in range(n):
      process(data[i])
  
  • breakcontinue 提前退出

一旦找到所需结果就立刻跳出循环,避免无谓遍历。

  • 考虑用集合或字典的 O(1) 查找替代列表的 O(n) 遍历

频繁的成员检查(if item in collection)应该使用 setdict,而不是 list

用生成器替代列表

生成器是“惰性求值”的,只在需要时才产生数据,能显著节省内存,同时减少一次性构建列表的时间开销。

  • 生成器表达式
  # 立刻构建完整列表,占用大内存
  squares = [x**2 for x in range(10**7)]

  # 生成器,几乎不占内存
  squares_gen = (x**2 for x in range(10**7))
  
  • 生成器函数

yield 一个个返回值,而不是一次性 return 一个巨大列表。

  • mapfilter 获得迭代器

Python 3 中它们返回迭代器而非列表,本身就是惰性操作。

合理选用数据结构

数据结构的操作复杂度直接决定性能天花板。

  • 查找频繁用 dictset,别用 list。字典的键查找为 O(1),列表为 O(n)。
  • 需要两头快速插入/删除用 collections.deque,而不是列表。列表头部插入 O(n),deque 两端操作 O(1)。
  • 需要有序的键值对用 OrderedDict 或 Python 3.7+ 的普通 dict(已保持插入顺序),但不要为了排序而频繁插入删除。
  • 绑定少量固定名字的元组用 namedtuple,避免创建完整类,内存更省、访问更快。

局部变量与属性访问优化

  • 将全局变量、模块属性赋值给局部变量

局部变量查找速度比全局变量快,因为局部变量在一个数组里用索引访问,而全局变量或对象属性需要字典查找。

  import math

  def slow():
      # 每次循环都在全局空间中找 math.sin
      for x in range(1000):
          y = math.sin(x)

  def fast():
      sin = math.sin          # 变成局部变量
      for x in range(1000):
          y = sin(x)
  
  • 减少对象属性链式访问

多次使用同一个对象的深层属性,比如 obj.a.b.c,应该先赋给一个局部变量,循环里直接使用该变量。

其他高频实用技巧

  • 字符串拼接:当拼接多个字符串时,用 ''.join(list_of_strs)++= 快得多,因为避免了大量临时字符串对象的创建。
  • 使用 slots 节省内存:类的属性固定时,定义 slots 可以阻止实例生成 dict,大幅减少内存占用并加快属性访问。
  • 避免在热点代码中使用装饰器包装:装饰器可能有函数调用开销,对性能极度敏感的代码可以暂时去掉它们。
  • 善用 functools.lru_cache:如果一些纯函数会被反复用相同参数调用,加上缓存装饰器能瞬间提速。

这些技巧不需要改变程序整体架构,也不要求你啃算法书,只要在写代码时多留一点心,就能把 Python 程序的“潜藏性能”挤出来。当然,优化前记得先用 timeitcProfile 找到真正的瓶颈——优化那 20% 的热点,往往能解决 80% 的性能问题。