C++ 开 O2 才干得过 Python?PyPy 竟如此强大!
  • 板块灌水区
  • 楼主CleanIce
  • 当前回复52
  • 已保存回复52
  • 发布时间2023/7/14 10:10
  • 上次更新2023/11/3 09:58:06
查看原帖
C++ 开 O2 才干得过 Python?PyPy 竟如此强大!
821660
CleanIce楼主2023/7/14 10:10

在我的博客中查看

最近了解到了 PyPy,听说它的速度非常快,我就做了一个实验。

可能还有人不知道 PyPy,咱们下面来解释一下:

PyPy简介:

PyPy 是用 Python 实现的 Python 解释器的动态编译器,是 Armin Rigo 开发的产品。

PyPy 采用 JIT(即时编译)技术,速度远高于 CPython。PyPy 与 RPython(强类型 Python 解释器)和 CPython(用 C 语言编写的 Python 解释器,是 Python 的原版本)共称三大 Python 解释器。

PyPy 的优点有:

  1. 速度快。CPython 解释代码,而 PyPy 编译代码。更重要的是,不用改 CPython 的代码就可以放在 PyPy 上运行。

  2. 占用内存少。PyPy 没有采用解释方式,所以没有解释器占用的内存。

  3. 版本更新快。目前 CPython 已达到 3.11,而 PyPy 也紧跟在 3.10。(两者版本差距并不大)

当然也有点缺点:

  1. 仍然需要包含 Python 环境。

  2. 对第三方库的支持没有 CPython 好,尤其是使用 C/C++ 拓展的库。以前还不兼容 Numpy,现在解决了。

实验开始

实验语言:CPython3.11,PyPy3.10,C++17(默认优化),C++17(O2优化)

实验程序要求:从终端输入一个数字,然后从 1 加到这个数字,打印结果和耗时。这里计算 1 加到 1 000 000 000(十亿)。

程序源码:

CPython & PyPy:

CPython & PyPy 源码

C++:

C++ 源码

实验结果:

咱们先来看 CPython:

CPython 运行结果

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

咱们再来看看 PyPy 做得怎么样:

PyPy 运行结果

啥? 2.0018 秒?能让 80 多秒的程序压到 2 秒运行,PyPy 也真是绝了。

接下来我满怀希望地编译 C++,相信它绝对能超过 PyPy。

C++ 默认优化编译指令(GNU):

g++ -std=c+=17 test.cpp -o test_normal

运行结果:

C++ 默认优化运行结果

???什么情况? 2.7840 秒?它竟然比 PyPy 还慢?

希望开了 O2 可以维护住 C++ 的尊严!

C++ O2 编译指令(GNU):

g++ -O2 -std=c++17 test.cpp -o test_o2

运行!

C++ O2 运行结果

C++ 成功地维护了它的尊严! 0.8020 秒!(真的太快了)

实验总结:

  1. 对速度要求快的程序,且想要少占内存、编写简易,使用 PyPy。

  2. 对第三方库有强烈依赖的,建议使用 CPython。

  3. Python 中有内存管理、整型无限扩容的功能。Python 的整型默认为 32 位,在运算溢出时扩充为 64 位,再就是 128 位、256位……我曾经将 Python 的整型扩充到了几百 MB。PyPy 同样有扩容功能。在这里显然扩容到了 64 位。即使在内存管理、整型扩容的束缚下,仍能超过默认优化的 C++,可见 PyPy 之强大。

  4. C++ O2 优化确实可以加快程序运行速度。很大可能是使用了 SIMD 技术。

SIMD 解释(摘抄于百度百科):

单指令流多数据流(英语:Single Instruction Multiple Data,缩写:SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据(又称“数据向量”)中的每一个分别执行相同的操作从而实现空间上的并行性的技术。

−−The End−−--The \space End--

2023/7/14 10:10
加载中...