最近了解到了 PyPy,听说它的速度非常快,我就做了一个实验。
可能还有人不知道 PyPy,咱们下面来解释一下:
PyPy 是用 Python 实现的 Python 解释器的动态编译器,是 Armin Rigo 开发的产品。
PyPy 采用 JIT(即时编译)技术,速度远高于 CPython。PyPy 与 RPython(强类型 Python 解释器)和 CPython(用 C 语言编写的 Python 解释器,是 Python 的原版本)共称三大 Python 解释器。
PyPy 的优点有:
速度快。CPython 解释代码,而 PyPy 编译代码。更重要的是,不用改 CPython 的代码就可以放在 PyPy 上运行。
占用内存少。PyPy 没有采用解释方式,所以没有解释器占用的内存。
版本更新快。目前 CPython 已达到 3.11,而 PyPy 也紧跟在 3.10。(两者版本差距并不大)
当然也有点缺点:
仍然需要包含 Python 环境。
对第三方库的支持没有 CPython 好,尤其是使用 C/C++ 拓展的库。以前还不兼容 Numpy,现在解决了。
实验语言:CPython3.11,PyPy3.10,C++17(默认优化),C++17(O2优化)
实验程序要求:从终端输入一个数字,然后从 1 加到这个数字,打印结果和耗时。这里计算 1 加到 1 000 000 000(十亿)。


咱们先来看 CPython:

可以看到,83.7578 秒,在预料之中,因为 CPython 真的比较慢。实际上 CPython3.11 已经优化过编译器了,运气好的话,其速度比 CPython3.11 要快 30% 到 40%。
咱们再来看看 PyPy 做得怎么样:

啥? 2.0018 秒?能让 80 多秒的程序压到 2 秒运行,PyPy 也真是绝了。
接下来我满怀希望地编译 C++,相信它绝对能超过 PyPy。
C++ 默认优化编译指令(GNU):
g++ -std=c+=17 test.cpp -o test_normal
运行结果:

???什么情况? 2.7840 秒?它竟然比 PyPy 还慢?
希望开了 O2 可以维护住 C++ 的尊严!
C++ O2 编译指令(GNU):
g++ -O2 -std=c++17 test.cpp -o test_o2
运行!

C++ 成功地维护了它的尊严! 0.8020 秒!(真的太快了)
对速度要求快的程序,且想要少占内存、编写简易,使用 PyPy。
对第三方库有强烈依赖的,建议使用 CPython。
Python 中有内存管理、整型无限扩容的功能。Python 的整型默认为 32 位,在运算溢出时扩充为 64 位,再就是 128 位、256位……我曾经将 Python 的整型扩充到了几百 MB。PyPy 同样有扩容功能。在这里显然扩容到了 64 位。即使在内存管理、整型扩容的束缚下,仍能超过默认优化的 C++,可见 PyPy 之强大。
C++ O2 优化确实可以加快程序运行速度。很大可能是使用了 SIMD 技术。
SIMD 解释(摘抄于百度百科):
单指令流多数据流(英语:Single Instruction Multiple Data,缩写:SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据(又称“数据向量”)中的每一个分别执行相同的操作从而实现空间上的并行性的技术。
−−The End−−