Cython-加速优化你的python代码,打包模块(一)

Basic Tutorial

Cython: 官网介绍说是具有C数据类型的python。cython可以看作是对python的一个扩展,使得python具有能够兼容C/C++的能力,其主要目的还是为了弥补python在执行效率上的短板, 此外也可以通过cython对核心模块进行编译起到一定的代码保护作用。

安装

pip3 install Cython
pip3 install Cython -i https://mirrors.aliyun.com/pypi/simple/

使用

Cython案例1:

查找质数,给定要查找质数的数量,返回对应数量的质数列表

参考官网: http://docs.cython.org/en/latest/src/tutorial/cython_tutorial.html
参考代码: https://github.com/chenyangMl/cython-pro/tree/master/BasicTutorial
$ git clone https://github.com/chenyangMl/cython-pro.git

  • 1、cython版本,新建example.pyx文件

    """
    prime(质数):  - 大于1的自然数 and 只能被1和自身整除的数
    """
    def primes(int nb_primes):
        cdef int n,i,len_p
        cdef int p[1000]
        if nb_primes > 1000:
            nb_primes = 1000
        len_p = 0
        n = 2
        while len_p < nb_primes:
            #Is n prime?
            for i in p[:len_p]:
                if n % i == 0:
                    break
            else:
                p[len_p] = n
                len_p += 1
            n +=1
        #保存c类型数组到python list
        res_list = [prime for prime in p[:len_p]]
        return res_list
    
  • 2 、纯python版本,新建example_py_cy.py

    def primes_python_compiled(nb_primes):
        p = []
        n = 2
        while len(p) < nb_primes:
            # Is n prime?
            for i in p:
                if n % i == 0:
                    break
    
            # If no break occurred in the loop
            else:
                p.append(n)
            n += 1
        return p
    
  • 3、编译,通过cython既可以编译.pyx文件也可以编译.py文件。新建setup.py

    #touch setup.py
    from distutils.core import setup
    from Cython.Build import cythonize
    
    setup (
        ext_modules = cythonize(["example.pyx",
                                 "example_py_cy.py"],
                                 annotate=True)
    )
    

    命令行编译 : $ python3 setup.py build_ext --inplace,每个被编译文件会对应生成三个文件

    编译文件 example.pyx example_py_cy.py 备注
    生成文件 example.c example_py_cy.c cython编译生成的C源码文件
    example.cexample.xxx.so example_py_cy.xxx.so 编译生成的二进制文件,可以通过import导入使用,模块名为exampel, example_py_cy
    example.html example_py_cy.html 当setup.py中cythonize的annotate为True时会生成的文件,里面可以显示的看到你写的代码那些是和python交互的,那些是直接与C交互的,如下图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ooOiQdoE-1570088799980)(./example.png)]
    Fig1 example.html

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OWy4cAF0-1570088799981)(./example_py_cy.png)]
    Fig 2example_py_cy.html

总结: 1:Fig1和Fig2分别表示代码example.pyx,example_py_cy.py文件中代码与python或C的交互程度,其中白色表示直接与C交互,而黄色表示与python交互,黄色越深表示与python的交互越多,即执行效率相对教慢。可以明显看到同任务函数,添加了C类型数据声明后的example.pyx中与python的交互要比未声明数据类型的example_py_cy少的多。

  • 4 编译模块的使用,编译后.py.pyx模块,可以通过import 直接导入使用。新建test.py

    #touch test.py
    import example
    import example_py_cy
    import time
    t1 = time.time()
    print(example.primes(10))
    print('cython-primes: ',time.time()-t1)
    t1 = time.time()
    print(example_py_cy.primes_python_compiled(10))
    print('python-primes: ',time.time()-t1)
      # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
      #cython-primes:1.5020370483398438e-05
      #[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
      #python-primes: 5.9604644775390625e-06
    

    总结: 测试时间说明通过声明变量数据类型代码的执行效率会得到提升,即代码执行时会减少与python的交互更多的变为与底层C的直接交互。同时也验证了上图Fig1,Fig2的代码交互示意图。

    Cython–python和cython代码性能分析(二)
    Cython–通过内存视图优化numpy(三)
    Cython–使用Cython封装C++代码(四)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章