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

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

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

星落发布于 2025/2/7更新于 2026/7/832 浏览
为什么 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. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 大模型周报:OpenAI GPT-Next 计划及多模态技术进展
  • 基于 RAG 技术的 AI 知识库构建与智能升级指南
  • 基于 7 系列 FPGA 实现万兆网通信
  • Spring Boot 配置属性自动绑定实战
  • MATLAB 实现基于 RRT-DNN 的无人机三维路径规划
  • 特征分解:线性代数在 AI 大模型中的核心工具
  • 大模型常见面试题汇总与答案解析
  • Spring Boot 数据访问与数据库集成详解
  • 基于 Leaflet 和天地图的免费运动场所 WebGIS 可视化
  • 沃尔玛:AI 助手 Sparky 凭速度与便利赢得信任
  • 10 款高效降低 AIGC 生成痕迹工具评测
  • PX4 飞控系统搭建与自主飞行实践指南
  • 程序员如何利用 AI 工具提升开发效率
  • VSCode GitHub Copilot 接入 OpenAI 兼容自定义模型方案
  • 解码 FPGA 底层架构:从触发器到时钟网络的硅视角
  • AIGC 中的变分自编码器(VAE)原理与代码实现
  • 用双栈模拟队列:深入理解 LIFO 到 FIFO 的转换策略
  • C++ AIGC 吞吐量优化实战:编译与运行时技巧提升 300%
  • Java 百度地图 SN 权限签名实践:搜索 2.0 接口示例
  • 黑客零基础入门教程:从零开始学习网络安全技术

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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