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++代碼(四)

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