PyPy 如何让Python代码运行得和C一样快
作者:赵卓不凡 发布时间:2022-07-16 20:17:58
1. 引言
作为一名算法工程师,如何快速实现一个想法并验证它是否有效对日常工作至关重要。Python 是一个出色的工具,可以很方便地实现这一点。它允许我们专注于想法本身,而不会被繁杂的代码实现所困扰。
然而,小伙伴们一定都听说过,Python脚本语言有一个致命缺点:相比比 C 或 C++ 等编译语言Python运行慢得多。那么,在我们通过构建 Python 快速实现了一个想法之后,现在我们想将它变成一个快速且高性能的工具,我们该怎么办?通常情况下,我们最终会耗费大概两倍的时间来将 Python 代码手动转换为 C/C++。
但是如果我们的 Python 代码本身可以运行得更快,那不是很好吗?那么如何实现呢?
幸运的是,我偶然发现了该问题的解决方案:PyPy,它是 Python运行时快速的替代品。
2. 举个栗子
为了直观对比 PyPy可以提升多少加速效果,我在以下示例中同时运行了默认的 Python 解释器和 使用PyPy,
代码如下:
import time
from termcolor import colored
start = time.time()
number = 0
for i in range(100000000):
number += i
print(colored("FINISHED", "green"))
print(f"Ellapsed time: {time.time() - start} s")
简单来说,上述脚本在一个循环中将 0 到 100,000,000 之间的所有整数相加,并在完成时打印一条消息和整个代码脚本运行时间。
对比结果如下:
尽管只是简单的对比,但上述例子的加速效果仍然令人兴奋。与大约需要 10 秒的默认 Python 解释器相比,PyPy 仅在 0.22 秒后就完成了执行!另外,请注意,我们可以直接将 Python 代码提供给 PyPy,而无需对代码做任何更改。
当我们将其与 C语言实现的版本进行比较时,结果会更加令人印象深刻。在我的电脑上,C 中的等效实现需要 0.32 秒。尽管在大多数情况下 C 总体上仍然是速度大师,但 PyPy 在某些情况下可以击败 C。
需要注意的是:
当我们的程序大部分运行时间都来自于调用非 python 库(比如Cpython)时,PyPy 的效率会降低。但是,如果我们有一个缓慢的程序,大部分时间都花在执行调用 Python库相关代码上时,那么 PyPy 可以极大地提升代码的运行效率。
3. 刨根问底
如果你也是第一次遇到 PyPy,那么您可能会问自己"PyPy运行这么快的背后原理是啥?"
额。。。 回顾我们的实验,我们运行完全相同的代码,并且使用 PyPy 似乎可以免费获得巨大的加速,黑科技哎。。。
其实尽管代码完全相同,但两种方式下的代码的执行方式却大不相同。 PyPy 性能提升的秘诀在于即时编译,简称 JIT 编译。
3.1 提前编译
C、C++ 以及 Swift、Haskell、Rust 等编程语言都是提前编译的。这意味着,在我们用这些语言编写了一些代码之后,需要点击一个build按钮,编译器就会将源代码转换为机器可读的代码,由一种特定的计算机架构读取。每当执行程序时,您的原始源代码早已不复存在。执行的只是机器代码。
3.2 语言可解释性
Python
、JavaScript
、PHP
等类似开发语言采用不同的方法。它们都是可以被解释的。与将源代码转换为机器代码相比,源代码保持不变。每次程序运行时,解释器都会逐行“查看”代码并为我们运行它。
对于 JavaScript
,每个 Web 浏览器都内置了一个解释器。标准的 Python 解释器称为 CPython。但是,区分 Python 语言脚本和运行代码的解释器工具是非常重要的,那是因为我们可以拥有完全不同的工具,它们都具有运行 Python 代码的能力。这就是 PyPy 发挥作用的地方。
3.3 即时编译
PyPy 是利用即时编译的 Python 的替代实现。背后的原理是 PyPy 开始时就像一个解释器,直接从源文件运行我们的 Python 代码。但是,PyPy 不是逐行运行代码,而是在执行它们之前将部分代码编译为机器代码,可以说是及时。
从这个意义上说,JIT 编译是解释和提前编译的结合。这样,我们不仅获得了提前编译的性能提升,而且解释性语言的灵活性和跨平台可用性也保留了下来。
4. 总结
现在我们了解了 PyPy 如何实现惊人的性能提升背后的原理。在官网 pypy.org 上免费提供PyPy安装包。除了工具本身,该网站还包含大量关于微调 Python 程序以进一步提高性能的技巧。由于 PyPy 只是 Python 的一种替代实现,大多数时候它都是开箱即用,无需对 Python 项目进行任何更改。它与 Web 框架 Django、科学计算包 Numpy 和许多其他包完全兼容,推荐大家多多使用。
来源:https://blog.csdn.net/sgzqc/article/details/122512172
猜你喜欢
- 本文实例讲述了Python进程的通信Queue、Pipe。分享给大家供大家参考,具体如下:内容相关:概念:进程的通信Queue:创建与使用P
- 如果你正在运行使用MySQL的Web应用程序,那么你把密码或者其他敏感信息保存在应用程序里的机会就很大。保护这些数据免受黑客或者窥探者的获取
- 1、Export/Import的用处 Oracle Export/Import工具用于在数据库之间传递数据。 Export从数据库中导出数据
- 导言很多Web程序都支持用户帐号,根据不同的登录用户提供不同的选项,报表等功能。例如,就我们的教程中,我们要允许供应商公司的一些账户能登录网
- 在JAVASCRIPT中LEFT函数的等价函数:function left(mainStr,lngLen) {if&nb
- 第一步 : 从清华大学开源软件镜像站下载Anaconda:https://mirrors.tuna.tsinghua.edu.cn/anac
- 在Django model中对一张表的几个字段进行联合约束和联合索引,例如在购物车表中,登录的用户和商品两个字段在一起表示唯一记录。举个栗子
- 如何在线更改Windows2000管理者密码?changepwd.htm <html><head><title
- Pyppeteer简介介绍Pyppeteer之前先说一下Puppeteer,Puppeteer是谷歌出品的一款基于Node.js开发的一款工
- 1 文件'''文件存储文件主名.扩展名'''Python中常有的数据文件类型有文本文件、二进
- Hihi, 大家好~ 最近有不少人都提及了网页上该如何选择字体的问题。问题虽然小,但是却是前端开发中的基本,因为目前的网页,还是以文字信息
- 大概在九九年做游戏网站的时候,就对文章的发布感到麻烦,不过那会儿玩ASP不精。只是将就用着。在遇到长文件 10000 字时网页就是一大片长了
- python 中提供一种用于对函数固定属性的函数(与数学上的偏函数不一样)# 通常会返回10进制int('12345') &
- 一、问题描述define function,calculate the input parameters and return the re
- 1.彻底弄懂CSS盒子模式一(DIV布局快速入门)3.彻底弄懂CSS盒子模式三(浮动的表演和清除的自述) 4.彻底弄懂CSS盒子模式四(绝对
- 在 Python 中,我们可以使用基本的索引操作来获取数组中的元素。然而,有时候我们需要获取一个数组的子数组,也就是只获取数组中的一部分元素
- 本文实例讲述了PHP编程实现多维数组按照某个键值排序的方法。分享给大家供大家参考,具体如下:实现对多维数组按照某个键值排序的两种解决方法(a
- 1 旖旎风景马上虎年了,也是我的生肖年,很激动!(不小心暴露了年龄,哈哈哈......),这里先给大家拜年啦,祝大家虎年快乐,虎年爆富!&n
- 在Oracle SQL的where子句中传入字符类型参数'19-11月-08',使得可以直接和日期类型比较,或者转换一下同日
- 本文实例为大家分享了Python实现信息管理系统的具体代码,供大家参考,具体内容如下"""项目名称 =