Python编程实战:从 timeit 到 cProfile,一次搞懂代码为什么慢

当你写 Python 写得越来越多,就会突然发现------有些代码运行得慢得离谱,但自己却不知道"慢"到底发生在哪一步。 这时你就需要真正的性能分析工具上场了,而不是继续凭感觉优化。

本篇我们一起搞定两大核心工具:

  • timeit:测函数执行时间
  • cProfile:分析整段程序的性能瓶颈

最后我会给你一个完整的优化示例,让性能提升看得见。


1. 为什么代码会慢?

Python 是解释型语言,灵活但速度不是强项。 代码变慢常见原因包括:

  • 不必要的循环
  • 低效的数据结构
  • 重复计算
  • IO 阻塞(文件/网络)
  • 第三方库使用不当

搞清楚瓶颈在哪里,是所有优化的起点。


2. 用 timeit 测局部性能:谁更快,一测便知

timeit 是个轻量级工具,非常适合比较小片段代码的速度。

例如:列表推导 vs for 循环,谁更快?

示例:用 timeit 测试代码片段

python 复制代码
import timeit

# 列表推导
expr1 = "[i*i for i in range(1000)]"
# 普通循环
expr2 = """
result = []
for i in range(1000):
    result.append(i*i)
"""

t1 = timeit.timeit(expr1, number=10000)
t2 = timeit.timeit(expr2, number=10000)

print("列表推导:", t1)
print("for 循环:", t2)

输出示例(依据电脑不同会变化)

makefile 复制代码
列表推导: 0.32
for 循环: 0.45

你一下就看出列表推导更快。 这就是 timeit 的价值: 用数字说话,而不是猜测。


3. 用 cProfile 查整段程序的瓶颈:慢在哪,一清二楚

当你不确定慢的是哪部分时,就用 cProfile

它会告诉你:

  • 每个函数调用几次
  • 每次耗时多久
  • 总耗时
  • 占比情况

超级适合分析中大型脚本。


示例:一个"看似没问题但其实很慢"的函数

python 复制代码
def slow_func():
    total = 0
    for i in range(10000):
        for j in range(10000):
            total += i + j
    return total

现在我们用 cProfile 分析:

python 复制代码
import cProfile

cProfile.run("slow_func()")

你会看到类似:

bash 复制代码
200000000 function calls in 3.821 seconds
ncalls  tottime  percall  cumtime  function
1       3.821    3.821    3.821    slow_func

一下就能看出: 问题全在 slow_func 本身,特别是双层循环。


4. 更清晰的结果?用 pstats 或 SnakeViz 可视化

默认输出较难读,你可以这样格式化:

python 复制代码
import cProfile
import pstats

with cProfile.Profile() as pr:
    slow_func()

stats = pstats.Stats(pr)
stats.sort_stats(pstats.SortKey.TIME)
stats.print_stats()

如果你想可视化展示(像瀑布图一样),可以安装 SnakeViz:

lua 复制代码
pip install snakeviz
snakeviz output.prof

非常适合技术分享或团队协作。


5. 实战:一步步从 2.5s 优化到 0.01s

假设我们有一个脚本统计每行是否包含某些关键词:

python 复制代码
def check_keywords(lines, keywords):
    result = []
    for line in lines:
        for k in keywords:
            if k in line:
                result.append((line, k))
    return result

分析:

  • 双层循环
  • 多次重复"是否包含"检查
  • 关键词过多时会超级慢

现在,我们用 cProfile 跑一下:

python 复制代码
cProfile.run("check_keywords(lines, keywords)")

你会看到绝大多数时间花在:

markdown 复制代码
str.__contains__

因为你对每个 line、每个 keyword 都在做 in 操作。


优化方案:把关键词变成正则 OR 模式

python 复制代码
import re

def fast_check_keywords(lines, keywords):
    pattern = re.compile("|".join(map(re.escape, keywords)))
    result = []
    for line in lines:
        m = pattern.search(line)
        if m:
            result.append((line, m.group()))
    return result

再跑性能测试

从 2.5 秒 → 0.01 秒 优化效果巨大。


6. 性能优化原则:永远遵循这三条

① 优化前先量化

不要凭直觉优化 永远先用 timeit / cProfile 查看瓶颈。

② 优化数据结构

例如:

  • 列表 → 集合(O(1) 查找)
  • 循环计算 → 内建函数/向量化

③ 避免重复计算

缓存、预编译、提前转换格式,都能救命。


7. 总结

性能优化是 Python 开发者进阶的必备技能。 timeit 解决"小范围速度比较", cProfile 负责"全局瓶颈定位"。

只要你掌握:

  • 定位
  • 调试
  • 替换更快的数据结构/算法

你就可以让脚本从"能跑"变成"飞快"。


相关推荐
hboot1 小时前
AI工程师第六课 - RAG检索增强生成
后端·langchain·llm
天才测试猿2 小时前
2026软件测试面试八股文(含答案+文档)
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
mldong2 小时前
jeeflow:98KB 的工作流引擎长什么样
后端
张小凡vip3 小时前
python--爬虫--成熟的爬虫框架Scrapy
爬虫·python·scrapy
Pluchon3 小时前
Java个人综合项目——萌部落社区V2.0
java·python·spring·spring cloud·postman·idea
不瘦80斤不改名4 小时前
01-vibe-coding-起源与本质
人工智能·python
夜雪一千4 小时前
如何对新闻数据进行模糊去重
python
程序员cxuan5 小时前
速度太快了!本地可以跑 DeepSeek-V4-Flash 了
人工智能·后端·程序员
anyup5 小时前
DeepSeek 这波涨价,我反而有点理解
ai编程·deepseek·trae
oyguyteggytrrwwwrt6 小时前
3dgs渲染部分详细注释
python