<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Cython三分鐘入門教程

        來源:懂視網 責編:小采 時間:2020-11-27 14:29:27
        文檔

        Cython三分鐘入門教程

        Cython三分鐘入門教程:作者:perrygeo譯者:賴勇浩(http://laiyonghao.com)原文:http://www.perrygeo.net/wordpress/p=116 我最喜歡的是Python,它的代碼優雅而實用,可惜純粹從速度上來看它比大多數語言都要慢。大多數人也認為的速度和易于使用是兩極對立的——編寫C代碼的確
        推薦度:
        導讀Cython三分鐘入門教程:作者:perrygeo譯者:賴勇浩(http://laiyonghao.com)原文:http://www.perrygeo.net/wordpress/p=116 我最喜歡的是Python,它的代碼優雅而實用,可惜純粹從速度上來看它比大多數語言都要慢。大多數人也認為的速度和易于使用是兩極對立的——編寫C代碼的確

        作者:perrygeo
        譯者:賴勇浩(http://laiyonghao.com)
        原文:http://www.perrygeo.net/wordpress/?p=116

        我最喜歡的是Python,它的代碼優雅而實用,可惜純粹從速度上來看它比大多數語言都要慢。大多數人也認為的速度和易于使用是兩極對立的——編寫C代碼的確非常痛苦。而 Cython 試圖消除這種兩重性,并讓你同時擁有 Python 的語法和 C 數據類型和函數——它們兩個都是世界上最好的。請記住,我絕不是我在這方面的專家,這是我的第一次Cython真實體驗的筆記:

        編輯:根據一些我收到的反饋,大家似乎有點混淆——Cython是用來生成 C 擴展到而不是獨立的程序的。所有的加速都是針對一個已經存在的 Python 應用的一個函數進行的。沒有使用 C 或 Lisp 重寫整個應用程序,也沒有手寫C擴展 。只是用一個簡單的方法來整合C的速度和C數據類型到 Python 函數中去。

        現在可以說,我們能使下文的 great_circle 函數更快。所謂 great_circle 是計算沿地球表面兩點之間的距離的問題:

        p1.py

        import math

        def great_circle(lon1,lat1,lon2,lat2):

        radius = 3956 #miles

        x = math.pi/180.0

        a = (90.0-lat1)*(x)

        b = (90.0-lat2)*(x)

        theta = (lon2-lon1)*(x)

        c = math.acos((math.cos(a)*math.cos(b)) +

        (math.sin(a)*math.sin(b)*math.cos(theta)))

        return radius*c

        讓我們調用它 50 萬次并測定它的時間 :

        import timeit

        lon1, lat1, lon2, lat2 = -72.345, 34.323, -61.823, 54.826

        num = 500000

        t = timeit.Timer("p1.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),

        "import p1")

        print "Pure python function", t.timeit(num), "sec"

        約2.2秒 。它太慢了!

        讓我們試著快速地用Cython改寫它,然后看看是否有差別:
        c1.pyx

        import math

        def great_circle(float lon1,float lat1,float lon2,float lat2):

        cdef float radius = 3956.0

        cdef float pi = 3.14159265

        cdef float x = pi/180.0

        cdef float a,b,theta,c

        a = (90.0-lat1)*(x)

        b = (90.0-lat2)*(x)

        theta = (lon2-lon1)*(x)

        c = math.acos((math.cos(a)*math.cos(b)) + (math.sin(a)*math.sin(b)*math.cos(theta)))

        return radius*c

        請注意,我們仍然import math——cython讓您在一定程度上混搭Python和C數據類型在。轉換是自動的,但并非沒有代價。在這個例子中我們所做的就是定義一個Python函數,聲明它的輸入參數是浮點數類型,并為所有變量聲明類型為C浮點數據類型。計算部分它仍然使用了Python的 math 模塊。

        現在我們需要將其轉換為C代碼再編譯為Python擴展。完成這一部的最好的辦法是編寫一個名為setup.py發布腳本。但是,現在我們用手工方式 ,以了解其中的巫術:

        # this will create a c1.c file - the C source code to build a python extension

        cython c1.pyx

        # Compile the object file

        gcc -c -fPIC -I/usr/include/python2.5/ c1.c

        # Link it into a shared library

        gcc -shared c1.o -o c1.so

        現在你應該有一個c1.so(或.dll)文件,它可以被Python import。現在運行一下:

        t = timeit.Timer("c1.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),

        "import c1")

        print "Cython function (still using python math)", t.timeit(num), "s

        約1.8秒 。并沒有我們一開始期望的那種大大的性能提升。使用 python 的 match 模塊應該是瓶頸。現在讓我們使用C標準庫替代之:

        c2.pyx

        cdef extern from "math.h":

        float cosf(float theta)

        float sinf(float theta)

        float acosf(float theta)

        def great_circle(float lon1,float lat1,float lon2,float lat2):

        cdef float radius = 3956.0

        cdef float pi = 3.14159265

        cdef float x = pi/180.0

        cdef float a,b,theta,c

        a = (90.0-lat1)*(x)

        b = (90.0-lat2)*(x)

        theta = (lon2-lon1)*(x)

        c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))

        return radius*cec"

        與 import math 相應,我們使用cdef extern 的方式使用從指定頭文件聲明函數(在此就是使用C標準庫的math.h)。我們替代了代價高昂的的Python函數,然后建立新的共享庫,并重新測試:

        t = timeit.Timer("c2.great_circle(%f,%f,%f,%f)" % (lon1,lat1,lon2,lat2),

        "import c2")

        print "Cython function (using trig function from math.h)", t.timeit(num), "sec"

        現在有點喜歡它了吧?0.4秒 -比純Python函數有5倍的速度增長。我們還有什么方法可以再提高速度?c2.great_circle()仍是一個Python函數調用,這意味著它產生Python的API的開銷(構建參數元組等),如果我們可以寫一個純粹的C函數的話,我們也許能夠加快速度。

        c3.pyx

        cdef extern from "math.h":

        float cosf(float theta)

        float sinf(float theta)

        float acosf(float theta)

        cdef float _great_circle(float lon1,float lat1,float lon2,float lat2):

        cdef float radius = 3956.0

        cdef float pi = 3.14159265

        cdef float x = pi/180.0

        cdef float a,b,theta,c

        a = (90.0-lat1)*(x)

        b = (90.0-lat2)*(x)

        theta = (lon2-lon1)*(x)

        c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))

        return radius*c

        def great_circle(float lon1,float lat1,float lon2,float lat2,int num):

        cdef int i

        cdef float x

        for i from 0 < = i < num:

        x = _great_circle(lon1,lat1,lon2,lat2)

        return x

        請注意,我們仍然有一個Python函數( def ),它接受一個額外的參數 num。這個函數里的循環使用for i from 0 < = i < num: ,而不是更Pythonic,但慢得多的for i in range(num):。真正的計算工作是在C函數(cdef)中進行的,它返回float類型。這個版本只要0.2秒——比原先的Python函數速度提高10倍。

        為了證明我們所做的已經足夠優化,可以用純C寫一個小應用,然后測定時間:

        #include

        #include

        #define NUM 500000

        float great_circle(float lon1, float lat1, float lon2, float lat2){

        float radius = 3956.0;

        float pi = 3.14159265;

        float x = pi/180.0;

        float a,b,theta,c;

        a = (90.0-lat1)*(x);

        b = (90.0-lat2)*(x);

        theta = (lon2-lon1)*(x);

        c = acos((cos(a)*cos(b)) + (sin(a)*sin(b)*cos(theta)));

        return radius*c;

        }

        int main() {

        int i;

        float x;

        for (i=0; i < = NUM; i++)

        x = great_circle(-72.345, 34.323, -61.823, 54.826);

        printf("%f", x);

        }

        用gcc -lm -o ctest ctest.c編譯它,測試用time ./ctest ...大約0.2秒 。這使我有信心,我Cython擴展相對于我的C代碼也極有效率(這并不是說我的C編程能力很弱)。

        能夠用 cython 優化多少性能通常取決于有多少循環,數字運算和Python函數調用,這些都會讓程序變慢。已經有一些人報告說在某些案例上 100 至 1000 倍的速度提升。至于其他的任務,可能不會那么有用。在瘋狂地用 Cython 重寫 Python 代碼之前,記住這一點:

        "我們應該忘記小的效率,過早的優化是一切罪惡的根源,有 97% 的案例如此。"——Donald Knuth

        換句話說,先用 Python 編寫程序,然后看它是否能夠滿足需要。大多數情況下,它的性能已經足夠好了……但有時候真的覺得慢了,那就使用分析器找到瓶頸函數,然后用cython重寫,很快就能夠得到更高的性能。

        外部鏈接
        WorldMill(http://trac.gispython.org/projects/PCL/wiki/WorldMill)——由Sean Gillies 用 Cython 編寫的一個快速的,提供簡潔的 python 接口的模塊,封裝了用以處理矢量地理空間數據的 libgdal 庫。

        編寫更快的 Pyrex 代碼(http://www.sagemath.org:9001/WritingFastPyrexCode)——Pyrex,是 Cython 的前身,它們有類似的目標和語法。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Cython三分鐘入門教程

        Cython三分鐘入門教程:作者:perrygeo譯者:賴勇浩(http://laiyonghao.com)原文:http://www.perrygeo.net/wordpress/p=116 我最喜歡的是Python,它的代碼優雅而實用,可惜純粹從速度上來看它比大多數語言都要慢。大多數人也認為的速度和易于使用是兩極對立的——編寫C代碼的確
        推薦度:
        標簽: 教程 分鐘 入門
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 久久精品免费一区二区| a级片免费在线播放| 国产h视频在线观看免费| 亚洲精品资源在线| 免费福利网站在线观看| 2020国产精品亚洲综合网| 国产精品免费观看久久| 国产成人精品日本亚洲语音| 国产免费私拍一区二区三区| 免费一区二区无码视频在线播放| 在线观看亚洲天天一三视| 18禁在线无遮挡免费观看网站| 久久精品国产亚洲av成人| 99久久免费中文字幕精品| 亚洲高清视频在线播放| 免费99精品国产自在现线| 亚洲精品国产第一综合99久久| 国产一级高清视频免费看| 国产成人高清精品免费观看| 亚洲精品国精品久久99热一| 91免费福利精品国产| 亚洲日本VA午夜在线电影| 亚洲国产精品毛片av不卡在线| 免费人成在线观看视频高潮| 亚洲黄色片在线观看| 毛片网站免费在线观看| 又黄又大的激情视频在线观看免费视频社区在线 | 免费人成大片在线观看播放电影 | 最近免费中文字幕大全高清大全1 最近免费中文字幕mv在线电影 | 久久aⅴ免费观看| 亚洲xxxx18| 精品国产亚洲男女在线线电影| 在线成人精品国产区免费| 亚洲一欧洲中文字幕在线| 亚洲av无码国产精品色在线看不卡 | 黄床大片免费30分钟国产精品| 亚洲爱情岛论坛永久| 国产国产人免费人成免费视频| 久久99精品免费一区二区| 亚洲人成网站色在线观看| 国产gv天堂亚洲国产gv刚刚碰|