一点cython





由于自我隔离,我们得以接触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的现成配方

使用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)


如果一切成功,那么输出将如下所示:




All Articles