跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表

目录

  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. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
Python算法

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

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

星落发布于 2025/2/70 浏览
为什么 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 程序的执行效率。

  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Python 入门基础教程:从环境配置到面向对象编程
  • 16 个 Python 开发中必知的实用技巧与最佳实践
  • Python 兼职与副业方向及技术实现指南
  • Python 七大主流职业方向与技术栈详解
  • Python 环境搭建与安装配置完整指南
  • 使用 Python 和 Selenium 进行浏览器自动化测试入门
  • Python 合并两个字典的 8 种常用方法
  • Python 代码打包成可执行文件的六种方法及对比分析
  • Mac 系统下 Anaconda 与 Python 环境安装完整指南
  • 基于 Python 构建与分析知识图谱及嵌入模型实战
  • C 语言与 Python 的核心区别及应用场景对比
  • Python 数据科学与机器学习领域十大核心库详解
  • Git 与 GitHub 入门指南:版本控制与协作实战
  • Python 为何发展迅速?基于 Stack Overflow 数据分析
  • 为什么选择 Python:核心特性与优势解析
  • Python 在职场中的多领域应用指南
  • Python 的三大主要用途:Web 开发、数据科学与脚本编写
  • Python 开发中应淘汰的旧模块与新替代方案指南
  • 13 个实用的 Python 自动化脚本示例
  • Python 自动化办公:基于 openpyxl 实现 Excel 数据汇总与填充

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,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

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online