爱上python系列------python性能(一):pypy实践

it2023-02-11  56

python作为一门解释型语言,执行效率一直被诟病,速度比c慢几十到上百倍

这里主要谈到pypy

就是一个解释器,我们安装好的python的默认的解释器是Cpython

比如我们平时使用python命令:

root@root:/opt# python Python 2.7.16 (default, Oct 7 2019, 17:36:04) [GCC 8.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>

这样的命令就是Cpython,上面写的很清楚,gcc呢:

 解释器的作用是将我们写好的python 代码(也就是所谓的源码)转换成机器码,这样的我们机器才能执行

而pypy主要利用jit技术,可以即时编译

Cpython作为解释器最大的问题一行一行的执行,这样就会非常慢 ,因此学会了使用类似jvm这样的方式

好了,我们来看看怎么使用pypy吧

我们可以将pypy想象成另外的一个python环境

 

一.安装pypy

1.下载压缩包:https://www.pypy.org/download.html

根据自己的系统进行 选择下载,这里我是选择py3.7的 linux

2.解压安装包

tar xf pypy-x.y.z.tar.bz2

解压内容我是放置是/opt/下的 

3.设置环境变量

对/etc/profile和~/.bashrc都加入如下内容

export PATH=/opt/pypy3.7-v7.3.2-linux64/bin:$PATH

刷新内容配置才会生效:

source /etc/profile source ~/.bashrc

4.试一下是否能够运行

root@root:/opt/pypy3.7-v7.3.2-linux64# pypy Python 3.7.4 (87875bf2dfd8, Sep 24 2020, 07:26:36) [PyPy 7.3.2-alpha0 with GCC 7.3.1 20180303 (Red Hat 7.3.1-5)] on linux Type "help", "copyright", "credits" or "license" for more information. >>>>

看看现在的解释器再也不是gcc了:

 

 二.安装需要的模块

我们知道,我们基本上都是还有pip进行安装第三方的包

pypy默认的是一个新环境,因此之前安装的包是没法使用的,需要重新安装,不信可以试一下:

cpython:

root@root:/opt/pypy3.7-v7.3.2-linux64# python3 -c "import numpy" root@root:/opt/pypy3.7-v7.3.2-linux64#

执行成功,说明numpy是没有安装的

pypy:

root@root:/opt/pypy3.7-v7.3.2-linux64# pypy -c "import numpy" Traceback (most recent call last): File "<string>", line 1, in <module> ModuleNotFoundError: No module named 'numpy'

发现是没有安装numpy的,因此我们需要自己手动安装numpy

安装之前需要安装pip

pypy -m ensurepip

这个命令成功后就可以安装好pip,安装好后最好再更新一下

pypy -mpip install -U pip wheel

现在我们就可以使用pip安装安装包了

使用命令:

pypy -mpip install 安装包名

比如我们的numpy 就该使用:

pypy -mpip install  numpy

细心的读者应该会注意到,在之前的python进行pip的时候是这样安装的:

pip install 安装包名或者python3 -mpip install 安装包名

归根结底,我们运行pypy命令直接代替了python3命令

不过值得注意的pypy -mpip install安装的速度会比之前的cpython环境下慢很多,不知道是不是我的电脑的原因。

 

三.对比cpython速度

例子是使用的《python忍者秘籍》7.4上的

1.新建一个名为time.py的文件,写入如下内容:

import math TIMES = 10000000 a = 1 b = 1 for i in range(TIMES): c = math.sqrt(math.pow(a, 2) + math.pow(b, 2)) a += 1 b += 2

2.新建一个名为time2.py的文件,写入如下内容:

import math TIMES = 10000000 a = 1 b = 1 def calcMath(i, a, b): return math.sqrt(math.pow(a, 2) + math.pow(b, 2)) for i in range(TIMES): c = calcMath(i, a, b) a += 1 b += 2

我们可以看到只是多了一个函数进行复用

接下来就剩下我们看结果了:

root@root:/opt/pypy3.7-v7.3.2-linux64# time pypy time.py real 0m1.049s user 0m0.992s sys 0m0.028s root@root:/opt/pypy3.7-v7.3.2-linux64# time pypy time2.py real 0m1.007s user 0m0.962s sys 0m0.020s root@root:/opt/pypy3.7-v7.3.2-linux64# time python3 time2.py real 0m6.578s user 0m6.536s sys 0m0.008s root@root:/opt/pypy3.7-v7.3.2-linux64# time python3 time.py real 0m5.682s user 0m5.636s sys 0m0.008s

可以看到pypy提速了不少,而且pypy对使用函数没有损耗 ,而原始的cpython就会损耗很多

当然需要在数据量很大的时候才能看到pypy和cpython速度的差距,数据量小的时候反而更慢都可能的

比如这个代码:

import time start=time.time() ls1=[i for i in range(1000)] ls2=[i for i in range(1000)] ls=ls2+ls1 end=time.time() print(end-start) """ 运行结果: root@root:/opt/pypy3.7-v7.3.2-linux64# python3 test.py 7.081031799316406e-05 root@root:/opt/pypy3.7-v7.3.2-linux64# pypy test.py 0.0001647472381591797 """

参考 :

[1].https://doc.pypy.org/en/latest/install.html

[2].《python忍者秘籍》

最新回复(0)