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

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忍者秘籍》

猜你喜欢

转载自blog.csdn.net/zhou_438/article/details/109178958