最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Cython 三分鐘入門教程

 更新時間:2009年09月17日 21:49:53   作者:  
根據一些我收到的反饋,大家似乎有點混淆——Cython是用來生成 C 擴展到而不是獨立的程序的。所有的加速都是針對一個已經存在的 Python 應用的一個函數進行的。

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

我最喜歡的是Python,它的代碼優(yōu)雅而實用,可惜純粹從速度上來看它比大多數語言都要慢。大多數人也認為的速度和易于使用是兩極對立的——編寫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發(fā)布腳本。但是,現在我們用手工方式 ,以了解其中的巫術:

# 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 模塊應該是瓶頸?,F在讓我們使用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。這個函數里的循環(huán)使用for i from 0 < = i < num: ,而不是更Pythonic,但慢得多的for i in range(num):。真正的計算工作是在C函數(cdef)中進行的,它返回float類型。這個版本只要0.2秒——比原先的Python函數速度提高10倍。

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

#include <math .h>

#include <stdio .h>

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

"我們應該忘記小的效率,過早的優(yōu)化是一切罪惡的根源,有 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 的前身,它們有類似的目標和語法。

相關文章

  • Python json格式化打印實現過程解析

    Python json格式化打印實現過程解析

    這篇文章主要介紹了Python json格式化打印實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Python?Pandas中append方法舉例詳解

    Python?Pandas中append方法舉例詳解

    這篇文章主要給大家介紹了關于Python?Pandas中append方法的相關資料,在Pandas中append()方法用于將一個或多個DataFrame或Series添加到DataFrame中,需要的朋友可以參考下
    2023-12-12
  • matplotlib圖例、標簽、坐標軸刻度的字體設置方式

    matplotlib圖例、標簽、坐標軸刻度的字體設置方式

    這篇文章主要介紹了matplotlib圖例、標簽、坐標軸刻度的字體設置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • pytorch中的squeeze函數、cat函數使用

    pytorch中的squeeze函數、cat函數使用

    這篇文章主要介紹了pytorch中的squeeze函數、cat函數使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • pycharm 使用tab跳出正在編輯的括號(){}{}等問題

    pycharm 使用tab跳出正在編輯的括號(){}{}等問題

    這篇文章主要介紹了pycharm 使用tab跳出正在編輯的括號(){}{}等問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 刪除PyCharm解釋器的方法步驟

    刪除PyCharm解釋器的方法步驟

    這篇文章主要給大家介紹了關于刪除PyCharm解釋器的方法步驟,PyCharm解釋器是指在PyCharm集成開發(fā)環(huán)境中用于運行和調試Python代碼的解釋器,需要的朋友可以參考下
    2023-09-09
  • python內置模塊OS?實現SHELL端文件處理器

    python內置模塊OS?實現SHELL端文件處理器

    這篇文章主要介紹了python內置模塊OS實現SHELL端文件處理器,文章通過圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Python字符串中添加、插入特定字符的方法

    Python字符串中添加、插入特定字符的方法

    這篇文章主要介紹了Python字符串中添加、插入特定字符的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • python中的print(f'')具體用法例子

    python中的print(f'')具體用法例子

    在Python中f-string是一種字符串格式化的方式,它允許你在字符串中嵌入變量或表達式的值,這篇文章主要給大家介紹了關于python中print(f'')具體用法例子的相關資料,需要的朋友可以參考下
    2024-05-05
  • Python Selenium參數配置方法解析

    Python Selenium參數配置方法解析

    這篇文章主要介紹了Python Selenium參數配置方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01

最新評論

厦门市| 修文县| 崇义县| 琼结县| 蓝山县| 信宜市| 临武县| 云林县| 静乐县| 赣榆县| 滦平县| 海丰县| 多伦县| 遂川县| 东乡| 丰都县| 吐鲁番市| 红原县| 永寿县| 当阳市| 旺苍县| 乃东县| 永靖县| 阳原县| 金山区| 商丘市| 云梦县| 九龙坡区| 乾安县| 高邮市| 全南县| 栾川县| 龙州县| 六枝特区| 瓮安县| 丰宁| 临洮县| 平凉市| 井研县| 方城县| 古田县|