跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

为什么 Python 代码在函数中运行得更快

解析了 Python 代码在函数中运行比全局范围更快的原因。核心在于变量存储机制:局部变量存储在固定长度数组中,通过索引直接访问;而全局变量存储在字典中,需进行哈希查找,开销更大。文章通过 dis 模块展示字节码差异(STORE_FAST vs STORE_NAME),利用 timeit 和 cProfile 进行基准测试验证,并给出了使用局部变量、内置函数等优化建议。

星落发布于 2025/2/7更新于 2026/9/453 浏览
为什么 Python 代码在函数中运行得更快

为什么 Python 代码在函数中运行得更快

当谈到编程效率和性能优化时,Python 常常被调侃为'慢如蜗牛'。有趣的是,在实际开发中发现,Python 代码在函数内部运行往往比在全局范围内(脚本顶层)运行要快得多。很多开发者可能会疑惑:为什么在函数中运行的 Python 代码速度更快?

Python 执行机制简述

要理解这一现象,首先需要了解 Python 是如何执行代码的。Python 是一种解释型语言,它会逐行读取并执行代码。当运行一个 Python 程序时,首先将源代码编译成字节码(一种更接近机器码的中间语言),然后 Python 解释器执行这些字节码。

需要注意的是,Python 解释器是一个执行字节码的虚拟机。默认的 Python 解释器是 CPython,它是用 C 编写的。此外还有 Jython(用 Java 编写)、IronPython(用于 .NET)和 PyPy(用 Python 和 C 编写)等其他实现。

Python 中的 dis 模块可以将函数分解为字节码指令,帮助我们查看底层执行细节。

局部变量与全局变量的存储差异

我们来通过一个简单的例子来对比。定义一个函数 my_function,函数内部包含一个 for 循环。

def my_function():
    for i in range(100):
        pass

编译该函数时,生成的字节码中包含关键指令 STORE_FAST,用于存储循环变量 i。这表示变量存储在局部作用域的快速数组中。

现在,我们将同样的 for 循环放在 Python 脚本的顶层(全局范围内):

for i in range(100):
    pass

再次查看其字节码,可以看到关键指令变成了 STORE_NAME,而不是 STORE_FAST。

核心原因分析

字节码 STORE_FAST 比 STORE_NAME 快,原因在于变量存储机制的不同:

  1. 局部变量:在函数中,局部变量存储在固定长度的数组中。这个数组可以通过索引直接访问,使得变量检索非常快。本质上,它只是一个指向列表的指针,并增加了 PyObject 的引用计数,这两个都是高效的操作。
  2. 全局变量:全局变量存储在一个字典(哈希表)中。当访问全局变量时,Python 必须执行哈希表查找,这涉及计算哈希值,然后检索与之关联的值。虽然经过优化,但仍然比基于索引的查找慢。

因此,减少全局变量的使用,尽量使用局部变量,是提升 Python 代码性能的关键策略之一。

基准测试验证

为了量化这种差异,我们可以使用 Python 内置的 timeit 模块对代码进行计时。

函数内执行

def factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

print(timeit.timeit('factorial(10)', setup='from __main__ import factorial', number=10000))

全局范围执行

result = 1
for i in range(1, 11):
    result *= i

print(timeit.timeit('result', 'from __main__ import result', number=10000))

注意:这两段代码最好不要放在同一脚本中同时运行,因为 benchmark() 函数在执行时间上增加了一些开销,且全局代码在内部进行了特定优化。分开单独运行更能反映真实差异。

测试结果通常显示,函数代码的执行速度明显优于全局作用域代码。

cProfile 性能分析

Python 提供了一个 cProfile 内置模块,用于分析代码的性能瓶颈。

让我们用它来分析一个新例子:在局部和全局范围内计算平方和。

# 局部版本
def sum_of_squares_local(n):
    total = 0
    for i in range(n):
        total += i * i
    return total

# 全局版本
total = 0
for i in range(1000):
    total += i * i

从性能分析结果中可以看到,函数代码在执行时间方面比全局代码更有效,主要消耗在函数调用开销上,但变量访问开销显著降低。

如何优化 Python 函数的性能

既然我们知道 Python 代码在函数中运行往往比在全局范围内运行要快得多,那么如何进一步优化呢?

1. 优先使用局部变量

避免在循环中使用全局变量。如果必须在循环中使用某个值,请将其赋值给局部变量。

# 不推荐:每次循环都查找全局变量
data = [1, 2, 3]
for item in data:
    print(item) 

# 推荐:使用局部变量
def process_data():
    local_data = [1, 2, 3]
    for item in local_data:
        print(item)

2. 使用内置函数和库

尽可能使用内置函数和标准库。Python 的许多内置函数是用 C 实现的,比纯 Python 代码快得多。

  • NumPy 和 Pandas:这些库底层使用 C 或 C++ 实现,处理数值运算和数据操作的速度远超原生 Python 列表。
  • 内置函数:同样是实现数字求和功能,Python 内置的 sum 函数要比自己编写循环速度快得多。
# 推荐
numbers = [1, 2, 3, 4, 5]
print(sum(numbers))

# 不推荐
print(sum([x for x in numbers])) # 额外生成列表

3. 避免不必要的属性查找

在类方法或函数中,频繁访问对象属性也会带来开销。可以将常用属性缓存到局部变量中。

总结

Python 代码在函数中运行更快的根本原因在于变量查找机制的差异:局部变量通过数组索引快速访问,而全局变量需要通过哈希表查找。通过遵循最佳实践,如封装代码到函数、使用局部变量以及利用高性能的内置库,可以显著提升 Python 程序的执行效率。

目录

  1. 为什么 Python 代码在函数中运行得更快
  2. Python 执行机制简述
  3. 局部变量与全局变量的存储差异
  4. 核心原因分析
  5. 基准测试验证
  6. 函数内执行
  7. 全局范围执行
  8. cProfile 性能分析
  9. 局部版本
  10. 全局版本
  11. 如何优化 Python 函数的性能
  12. 1. 优先使用局部变量
  13. 不推荐:每次循环都查找全局变量
  14. 推荐:使用局部变量
  15. 2. 使用内置函数和库
  16. 推荐
  17. 不推荐
  18. 3. 避免不必要的属性查找
  19. 总结

更多推荐文章

查看全部
  • MySQL Online DDL 三大算法 INSTANT、INPLACE、COPY 差异详解
  • 解决新机型 Copilot 键替代右 Ctrl 键问题
  • 国产开源 AI 工具爱派 (AiPy) 支持本地部署与 Python 自动化办公
  • ONNX Runtime C++ 推理入门与实战
  • 手写 C++ TCP 服务器:自定义协议与粘包处理实战
  • RTX 3060 12G 量化部署 CodeLlama-7B 实战指南
  • DeepSeek 在主流云电脑平台的部署体验对比
  • OpenClaw 开源 AI 助手安装配置与高级玩法实战
  • VS Code GitHub Copilot 插件无法加载模型排查指南
  • Superpowers 编码 Agent 技能框架使用与原理分析
  • C++ 网络编程实战指南:从基础到进阶
  • CPU+GPU+FPGA 异构计算 AI 系统调优:协同计算资源调度策略
  • 基于 LLaMA-Factory 的大模型部署与微调实战
  • VS Code Copilot 接入第三方 OpenAI 兼容模型配置指南
  • Vivado 入门实战:从工程创建到比特流烧录
  • SQL 表查询基础:SELECT 语句详解
  • 文科生利用 Python+AI 进行应用开发与变现实战
  • Python 抽象基类(ABC)核心概念与实战
  • 开源电路板查看器 OpenBoardView:.brd 文件解析工具
  • 工程管理系统功能设计与技术架构解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online