Python 优化 在 跳过 这一步 时 失败
抱歉,我需要您提供要翻译的完整文本(除代码块和 URL 之外的内容),才能为您进行翻译。请把文章的正文粘贴在这里,我会按照要求保留源链接并保持原有的格式进行翻译。
大多数开发者面临的问题
你注意到你的 Python 脚本运行缓慢。你已经阅读了关于优化的文章。你知道列表推导式比循环更快。你听说 NumPy 很快。所以你开始重写代码。
问题出在哪里:你是基于假设而不是数据进行优化的。
每个人都会跳过的那一步
在优化之前先进行性能分析。
大家都这么说,但大多数开发者(包括过去的我)直接跳到优化阶段。
一个改变我方法的真实案例
def process_sales_data(filename):
df = pd.read_csv(filename)
# Calculate profit for each row
profits = []
for index, row in df.iterrows():
profit = row['revenue'] - row['cost']
profits.append(profit)
df['profit'] = profits
# Filter and group
profitable = df[df['profit'] > 100]
averages = profitable.groupby('region')['profit'].mean()
return averages
处理 100,000 行耗时 42 秒 —— 太慢了。
性能分析揭示的内容
import cProfile
import pstats
from io import StringIO
profiler = cProfile.Profile()
profiler.enable()
process_sales_data('sales.csv')
profiler.disable()
stream = StringIO()
stats = pstats.Stats(profiler, stream=stream)
stats.sort_stats('cumulative')
stats.print_stats(20)
print(stream.getvalue())
输出让我大吃一惊:
iterrows()循环消耗了 90 % 的运行时间。- 我担心的
groupby?仅占 2 %。
修复很简单
def process_sales_data(filename):
df = pd.read_csv(filename)
# Vectorized operation – no loop
df['profit'] = df['revenue'] - df['cost']
# Same filtering and grouping
profitable = df[df['profit'] > 100]
averages = profitable.groupby('region')['profit'].mean()
return averages
运行时间从 42 秒 降至 1.2 秒 – 通过更改三行代码实现了 35× 的加速。
为什么我们的直觉会失效
- 我们关注语法,而不是执行成本。 嵌套循环看起来很慢,但如果它们只在 10 条数据上运行一次,那就无关紧要。一次处理 100,000 条数据的函数调用更值得关注。
- 我们低估了 Python 的开销。 在 pandas 中逐行迭代会产生巨大的开销;看似简单的操作会触发成千上万的操作。
- 我们认为最近的更改导致了慢速。 通常慢速一直存在,只是我们在数据规模扩大后才注意到。
- 我们优化我们理解的部分。 我理解分组操作,所以把注意力放在那里。真正的问题是我没有考虑到的东西。
如何正确进行性能分析
import cProfile
import pstats
profiler = cProfile.Profile()
profiler.enable()
your_function()
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative') # Sort by total time including calls
stats.print_stats(20) # Show top 20 functions
首先查看 cumtime 列。它表示包括嵌套调用在内的总时间。cumtime 最高的函数就是你的主要目标。
我现在遵循的模式
- 测量基准性能 – 对完整操作计时。
- 分析找出瓶颈 – 使用
cProfile,而不是凭猜测。 - 优化最主要的瓶颈 – 修复实际消耗时间的部分。
- 再次测量 – 验证改进效果。
- 如有必要重复 – 再次分析以发现下一个瓶颈。
这种系统化的方法每次都能胜过直觉。
常见的性能分析发现
- 数据库查询消耗 80 %+ 的运行时间(优化查询,而不是 Python 代码)。
- 文件 I/O 主导数据处理脚本(使用缓冲操作,采用二进制格式)。
- pandas 中逐行迭代会产生巨大的开销(全部向量化)。
- 循环中的字符串拼接导致 O(n²) 行为(改用
''.join())。 - 不必要的对象创建会增加垃圾回收压力(复用缓冲区)。
仅凭阅读代码是找不到这些问题的。只有通过性能分析才能发现。
课程
在花费数小时优化 Python 代码之前:
- 不要根据博客文章重写已工作的代码。
- 不要假设自己知道慢的部分。
- 不要一次优化多件事。
- 不要跳过测量。
先进行剖析。 每次都要。
想深入了解 Python 优化吗? 查看完整指南:Python Optimization Guide: How to Write Faster, Smarter Code.