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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

基准测试验证

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

如何优化 python 函数的性能

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

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

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

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

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

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

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

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

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

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

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

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

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

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

标签:
  • 热门焦点
  • 线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • Flowable工作流引擎的科普与实践

    一.引言当我们在日常工作和业务中需要进行各种审批流程时,可能会面临一系列技术和业务上的挑战。手动处理这些审批流程可能会导致开发成本的增加以及业务复杂度的上升。在这
  • 学习JavaScript的10个理由...

    作者 | Simplilearn编译 | 王瑞平当你决心学习一门语言的时候,很难选择到底应该学习哪一门,常用的语言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 让我们一起聊聊文件的操作

    文件【1】文件是什么?文件是保存数据的地方,是数据源的一种,比如大家经常使用的word文档、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存数据,它既可以保
  • 信通院:小米、华为等11家应用商店基本完成APP签名及验签工作

    中国信通院表示,目前,小米、华为、OPPO、vivo、360手机助手、百度手机助手、应用宝、豌豆荚和努比亚等9家应用商店,以及抖音和快手2家新型应用分发平
  • iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    日前iQOO手机官方宣布,新一代电竞旗舰iQOO 11S将会在7月4日19:00正式与大家见面。随着发布时间的日益临近,官方关于该机的预热也更加密集,截至目前已
  • iQOO Neo8 Pro评测:旗舰双芯加持 最强性能游戏旗舰

    【Techweb评测】去年10月,iQOO推出了一款Neo7手机,该机搭载了联发科天玑9000+,配备独显芯片Pro+,带来了同价位段最佳的游戏体验,一经上市便受到了诸多用
Top