由于自我隔离,我们得以接触Cythona。问题是平淡无奇的-如何以最小的语法损失加快python的速度。一种方法是使用Cython(C和python的混合物)。标题很大
的出版物困扰着。但是,从出版物的内容中学到的很少,因为公式和结果表不正确。让我们尝试完成帖子作者创建的图片,并在和上加点。
*测试是在odroid xu4,ubuntu mate,python 2.7.17上进行的。
Cython易于安装(pip install cython)。
我们将折磨所有相同的斐波那契数字。让我们创建用于性能提升测试的文件。对于python语言(test.py):
def test(n):
a, b = 0.0, 1.0
for i in range(n):
a, b = a + b, a
print (a)
对于cython语言(test2.pyx):
def test2(int n):
cdef int i
cdef double a=0.0, b=1.0
for i in range(n):
a, b = a + b, a
print (a)
cython文件需要预先构建。让我们为其创建一个setup.py,其中包含以下内容:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('test2.pyx'))
并收集:
python setup.py build_ext --inplace
现在,让我们从上面提到的帖子中获取带有测试的文件,并通过添加在开头输入您自己的数字的能力来对其进行修正(tests.py):
import test
import test2
import time
number = input('enter number: ')
start = time.time()
test.test(number)
end = time.time()
py_time = end - start
print("Python time = {}".format(py_time))
start = time.time()
test2.test(number)
end = time.time()
cy_time = end - start
print("Cython time = {}".format(cy_time))
print("Speedup = {}".format(py_time / cy_time))
让我们看看发生了什么:
python tests.py
结果:
对于python 2.7:
enter number: 10
Python time = 1.62124633789e-05
Cython time = 4.05311584473e-06
Speedup = 4.0
enter number: 100
Python time = 3.40938568115e-05
Cython time = 5.00679016113e-06
Speedup = 6.80952380952
enter number: 1000
Python time = 0.000224113464355
Cython time = 1.19209289551e-05
Speedup = 18.8
enter number: 100000
Python time = 0.0200171470642
Cython time = 0.000855922698975
Speedup = 23.3866295265
对于python 3:
enter number: 10
Python time = 7.653236389160156e-05
Cython time = 2.8133392333984375e-05
Speedup = 2.7203389830508473
enter number: 100
Python time = 8.678436279296875e-05
Cython time = 3.170967102050781e-05
Speedup = 2.736842105263158
enter number: 1000
Python time = 0.00031876564025878906
Cython time = 4.673004150390625e-05
Speedup = 6.821428571428571
enter number: 100000
Python time = 0.01643967628479004
Cython time = 0.0004260540008544922
Speedup = 38.5858981533296
*使用以下命令“重新构建”了test2.pyx模块:
python3 setup.py build_ext --inplace
**由cython
安装:pip3 install cython
您无需使用setup.py来构建test2.pyx即可,为此,您只需将行添加到tests.py文件中:
import pyximport
pyximport.install()
现在,每次运行tests.py时,test2.pyx都会动态生成,并且该文件夹中的文件会更少。
如何在Windows上启动cython。
尽管cython允许为python3和python2都组装文件,
使用python3,build命令可以运行:
python setup.py build_ext -i --compiler=msvc
但是,要完成其完整的工作,您需要安装Visual Studio 2019组件的一部分。此处的解决方案中指出了要确切安装的组件。
因此,有两个工作选项可让您使用cython在Windows中工作(构建文件)。
第一个使用python2.7和mingw编译器。
步骤如下。
1,在python2.7下安装cython本身:
py -2 -m pip install cython
2.安装mingw编译器:
mingw
3.安装编译器并将其添加到PATH窗口后,可以使用以下命令编译.pyx文件:
python setup.py build_ext -i --compiler=mingw32
第二个是使用python3.x和msvc编译器。
如何在Jupyter Notebook中运行cython。
有时有必要使用jupyter直观地测试代码的工作。为了不每次都在cmd中编译代码,可以在jupyter单元中使用cython。
为此,请在jupyter单元中执行以下操作导入cython:
%load_ext cython
让我们在下一个单元格中执行一些代码:
%%cython -a
import numpy as np
cdef int max(int a, int b):
return a if a > b else b
cdef int chebyshev(int x1, int y1, int x2, int y2):
return max(abs(x1 - x2), abs(y1 - y2))
def c_benchmark():
a = np.random.rand(1000, 2)
b = np.random.rand(1000, 2)
for x1, y1 in a:
for x2, y2 in b:
chebyshev(x1, x2, y1, y2)
如果一切成功,那么输出将如下所示: