Python之父的加速秘籍:PyPy能让代码运行得更快

开发 后端
实话讲,Python很慢,而用Python(!)编写的Python在运行时,执行速度比CPython快4.4倍。这是如何实现的呢?

本文转载自公众号“读芯术”(ID:AI_Discovery)。

当我们提及Python时,常常指的是CPython,即C语言实现的Python,这就是PyPy发挥作用的地方啦。实话讲,Python很慢,而用Python(!)编写的Python在运行时,执行速度比CPython快4.4倍。这是如何实现的呢?

[[340776]]

正如Python之父吉多·范罗苏姆(Guido van Rossum)所说:“如果想让代码运行得更快,应该使用PyPy。”

第一批使用PyPy的程序员竞争力很强。有时候,就算花了很多时间用Python编写解决方案,最后也会失败,但是在PyPy中运行同样的代码就会成功。这是为什么?

不同的方法

Python是一种解释性语言,CPython逐行读取并执行源代码。解释性语言(包括JavaScript)有很多优点:

  • 易于编写
  • 元编程能力强大
  • 编译不会失败

当然,它也有一些缺点:

  • 在解析源代码时,性能消耗巨大
  • 编译不会失败

可以看到,其优缺点都包括了“编译不会失败”。这有时候基于不同的行为(比如原型设计或生产),但我仍然倾向于将其视为一个缺点。而PyPy稍有不同,它不是一个纯粹的解释器,而是实现了跟踪即时(JIT)编译。

即时编译

即时编译介于解释和传统提前编译之间。即时编译器并不执行源代码本身,而是生成一组可立即执行的低层指令(通常是汇编)。

这个插图可以帮助我们理解其中的区别。在编译语言(C、C++、Rust)中,编译阶段严格按照开发环境划分。它生成一个可运行的二进制文件,然后将其发送到生产环境中。

在解释性语言中,情况正好相反:源代码(在*化之后,hello JS)被全部推到生产环境中,由解释器执行。即时编译语言也运送源代码(或字节码,如Java或C#),但它是作为一种常规编译语言编译和运行,而不是逐行解释。

并不是说一种方法比另一种好,每个用例都将根据其独特的需求指定正确的选择。但是,如果性能非常关键,使用Python解释器感觉很舒服,那么你可以选择PyPy。

跟踪即时编译

与编译或解释一样,实现即时编译也有不同的方法。传统的方法是方法/函数作用域。当代码调用一个函数时,即时编译器将获得它的源代码,进行编译并提供可执行的二进制文件。而PyPy采用的方法稍微不同,这是由Python的特性和用例决定的。

PyPy的编译器不是按方法调用,而是计算循环。由于Python在数据科学、机器学习、高级算法以及数据结构中使用广泛,这是最有意义的。简而言之,PyPy是Python之上的一个优化层。

PyPy并不像所理解的那样严格处理循环。除了常规的for和while结构外,如果PyPy检测到编译工作有价值,它会优化任意代码块。

缺点

[[340777]]

图源:unsplash

当然,PyPy也有缺点。即使它能大大提高性能,你也需要知道以下几点:

  • 不支持所有的Python。它支持大部分代码,但是如果处理底层的CPython实现细节或者有Cython绑定,它就不起作用了。
  • 回溯未来。PyPy当前版本是3.4,而Python目前稳定在3.8,但是回溯法是Python开发者擅长的技术。
  • 优化是好事,但不是编写糟糕代码的借口。如果代码无法被人读懂, PyPy又怎能理解呢?
  • 全局解释器锁还在。如果执行繁重的多线程操作,请选择其他实现方法。

与任何工具一样,在采用之前,我们应该考虑所有的细节。不过,下次登录到Codeforces接受挑战时,不妨试用一下PyPy。有可能O(n^3)错误代码会通过,而在纯Python中,只有O(n log n)会通过。

源代码

虽然本文没有涉及CPython和PyPy的源代码,但是这些文件在CPython (C代码)和PyPy (Python代码)中实现了阶乘函数。

  • CPython:https://github.com/python/cpython/blob/master/Modules/mathmodule.c
  • PyPy:https://github.com/mozillazg/pypy/blob/50d6bf76ef1f93c234ab42d4dd4a3b974f9665d6/pypy/module/math/app_math.py

其他实现

除了CPython和PyPy,还有其他值得注意的Python实现:

  • StacklessPython。它和Python相同,但没有全局解释器锁,《星战前夜》游戏后端用的就是它。
  • IronPython是一种在 NET上实现的 Python 语言,它为Python和c#代码提供了非常简单的交互操作。
  • JPython同理,但是有Java。

去试试使用PyPy来体验代码加速度吧!

 

责任编辑:赵宁宁 来源: 今日头条
相关推荐

2023-09-20 00:06:30

Python代码函数

2012-09-11 09:16:52

Hadoop

2023-06-26 07:21:41

标题栏鼠标标题

2021-12-14 12:10:41

ChromeWindows浏览器

2020-09-02 14:00:05

Python代码脚本

2019-03-29 09:00:11

Windows 10PC模拟器

2022-06-22 10:33:06

麻省理工大学PaShUnix shell

2021-05-04 22:13:56

PyPyPythonC

2013-03-25 09:41:20

PythonCython

2022-06-16 14:17:54

网络网速

2012-12-27 17:43:11

应用商店开发者

2013-05-17 09:40:11

2012-09-06 09:36:17

谷歌NatiShalom数据处理

2024-02-21 20:43:02

Python列表推导式

2020-07-23 14:15:42

Cython的Python代码

2024-01-08 17:09:07

Python解释器CPython

2021-11-11 06:57:00

PythonPyPy程序

2022-01-06 22:31:21

Python技巧代码

2015-08-20 10:05:15

Python

2020-11-02 09:07:41

Pyston v2.0Python
点赞
收藏

51CTO技术栈公众号