当前位置:首页 > 科技  > 软件

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

来源: 责编: 时间:2023-09-20 21:54:44 215观看
导读要理解为什么 Python 代码在函数中运行得更快,我们需要首先了解 Python 是如何执行代码的我们知道,python 是一种解释型语言,它会逐行读取并执行代码当运行一个 python 程序的时候,首先将代码编译成字节码(一种更接近机器

要理解为什么 Python 代码在函数中运行得更快,我们需要首先了解 Python 是如何执行代码的kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

我们知道,python 是一种解释型语言,它会逐行读取并执行代码kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

当运行一个 python 程序的时候,首先将代码编译成字节码(一种更接近机器码的中间语言)然后 python 解释器执行字节码kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

由上所示,python 中的 dis 模块将函数 hello_world 分解为字节码kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

需要注意的是,python 解释器是一个执行字节码的虚拟机,默认的 python 解释器是用 C 编写的,即 CPythonkcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

还有其他的 python 解释器如 Jython(用 Java 编写),IronPython(用于 )和PyPy(用 Python 和 C 编写)kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

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

kcy28资讯网——每日最新资讯28at.com

我们来编写一个简单的例子:定义一个函数 my_function,函数内部包含一个 for 循环kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

编译该函数的时候,字节码可能如下所示kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

这里的关键指令是 STORE_FAST ,用于存储循环变量 i kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

现在我们把这个 for 循环放在 python 脚本的顶层(全局范围内),然后再来看一下字节码kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

可以看到关键指令变成了 STORE_NAME,而不是 STORE_FAST kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

字节码 STORE_FAST比 STORE_NAME 快,因为在函数中,局部变量存储在固定长度的数组中,而不是存储在字典中。这个数组可以通过索引直接访问,使得变量检索非常快kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

基本上,它只是一个指向列表的指针,并增加了 PyObject 的引用计数,这两个都是高效的操作kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

另一方面,全局变量存储在一个字典。当访问全局变量时,Python 必须执行哈希表查找,这涉及计算哈希值,然后检索与之关联的值kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

虽然经过优化,但仍然比基于索引的查找慢kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

基准测试验证

kcy28资讯网——每日最新资讯28at.com

我们知道在 Python 中,代码执行的速度取决于代码执行的位置——在函数中还是在全局作用域中kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

让我们用一个简单的基准测试的例子来比较一下kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

首先定义一个求阶乘的函数kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

然后在全局范围内执行相同的代码kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

为了对这两段代码进行基准测试,我们可以在 Python 中使用 timeit 模块,它提供了一种简单的方法来对少量 Python 代码进行计时kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

可以看到,函数代码的执行速度比全局作用域代码要快kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

需要注意的是,这两段代码最好不要放在同一脚本中,要分开单独运行kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

这是因为 benchmark() 函数在执行时间上增加了一些开销,并且全局代码在内部进行了优化kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

cProfile 分析kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

python 提供了一个  cProfile 内置模块kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

让我们用它来分析一个新例子:在局部和全局范围内计算平方和kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

上面的例子中,可以认为sum_of_squares_g() 函数是全局的,因为它使用了两个全局变量, i 和 totalkcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

从性能分析结果中,可以看到函数代码在执行时间方面比全局更有效kcy28资讯网——每日最新资讯28at.com

图片图片kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

如何优化 python 函数的性能

kcy28资讯网——每日最新资讯28at.com

前面我们知道,Python 代码在函数中运行往往比在全局范围内运行要快得多kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

如果想要进一步提高 python 函数代码效率,不妨考虑一下使用局部变量而不是全局变量kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

另一种方法是尽可能使用内置函数和库。Python 的内置函数是用 C 实现的,比 Python 快得多kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

比如 NumPy 和 Pandas,也是用 C 或 C++ 实现的,它们比实现同样功能的 Python 代码速度更快kcy28资讯网——每日最新资讯28at.com

kcy28资讯网——每日最新资讯28at.com

又比如同样是实现数字求和的功能,python 内置的 sum 函数要比你自己编写函数速度更快kcy28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-10609-0.html为什么 Python 代码在函数中运行得更快?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 使用二进制字面量在现代C++中的应用

下一篇: 数据组合利器:从入门到精通Python中的zip()函数应用

标签:
  • 热门焦点
Top