溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

cython與python有什么不同

發(fā)布時(shí)間:2020-09-21 14:22:07 來(lái)源:億速云 閱讀:206 作者:Leah 欄目:編程語(yǔ)言

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)cython與python有什么不同,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Cython是Python的一個(gè)超集,結(jié)合了Python的易用性和原生代碼的速度,可以編譯成C語(yǔ)言,產(chǎn)生的性能提升可以從幾個(gè)百分點(diǎn)到幾個(gè)數(shù)量級(jí),具體取決于手頭的任務(wù)。

使用Cython,你可以避開(kāi)Python的許多原生限制,或者完全超越Python,而無(wú)需放棄Python的簡(jiǎn)便性和便捷性。

Python代碼可以直接調(diào)用C模塊。這些C模塊可以是通用的C庫(kù)或?qū)iT(mén)為Python工作的庫(kù)。Cython生成第二種類(lèi)型的模塊:與Python內(nèi)部對(duì)話(huà)的C庫(kù),可以與現(xiàn)有的Python代碼綁定在一起。

Cython代碼在設(shè)計(jì)上看起來(lái)很像Python代碼。如果你給Cython編譯器提供了一個(gè)Python程序,它將會(huì)按原樣接受它,但是Cython的原生加速器都不會(huì)起作用。但是如果你用Cython的特殊語(yǔ)法來(lái)修飾Python代碼,那么Cython就可以用快速的C代替慢的Python對(duì)象。

請(qǐng)注意,Cython的方法是漸進(jìn)的。這意味著開(kāi)發(fā)人員可以從現(xiàn)有的Python應(yīng)用程序開(kāi)始,通過(guò)對(duì)代碼立刻進(jìn)行更改來(lái)加快速度,而不是從頭開(kāi)始重寫(xiě)整個(gè)應(yīng)用程序。

這種方法通常與軟件性能問(wèn)題的性質(zhì)相吻合。在大多數(shù)程序中,絕大多數(shù)CPU密集型代碼都集中在一些熱點(diǎn)上,也就是帕累托原則的一個(gè)版本,也被稱(chēng)為“80/20”規(guī)則。因此,Python應(yīng)用程序中的大部分代碼不需要進(jìn)行性能優(yōu)化,只需要幾個(gè)關(guān)鍵部分。你可以逐漸將這些熱點(diǎn)轉(zhuǎn)換為Cython,從而獲得你最需要的性能提升。程序的其余部分可以保留在Python中,以方便開(kāi)發(fā)人員。

Cython優(yōu)勢(shì)

除了能夠加速已經(jīng)編寫(xiě)的代碼之外,Cython還具有其他幾個(gè)優(yōu)點(diǎn):

使用外部C庫(kù)可以更快

像NumPy這樣的Python軟件包可以在Python界面中打包C庫(kù),使它們易于使用。但是,這些包在Python和C之間來(lái)回切換會(huì)減慢速度。Cython可以讓你直接與底層庫(kù)進(jìn)行通信,而不需要Python(也支持C ++庫(kù))。

可以同時(shí)使用C和Python內(nèi)存管理

如果你使用Python對(duì)象,它們就像在普通的Python中一樣被內(nèi)存管理和垃圾收集。但是如果你想創(chuàng)建和管理自己的C級(jí)結(jié)構(gòu),并使用malloc/free來(lái)處理它們,你可以這樣做,只記得自己清理一下。

可以根據(jù)需要選擇安全性或速度

Cython通過(guò)decorator 和編譯器指令(例如@boundscheck(False))自動(dòng)執(zhí)行對(duì)C中彈出的常見(jiàn)問(wèn)題的運(yùn)行時(shí)檢查,例如對(duì)數(shù)組的超出邊界訪問(wèn)。因此,由Cython生成的C代碼默認(rèn)比手動(dòng)C代碼安全得多。

如果確信在運(yùn)行時(shí)不需要這些檢查,則可以在整個(gè)模塊上或僅在選擇功能上禁用它們以獲得額外的編譯速度。

Cython還允許本地訪問(wèn)使用“緩沖協(xié)議”的Python結(jié)構(gòu),以直接訪問(wèn)存儲(chǔ)在內(nèi)存中的數(shù)據(jù)(無(wú)需中間復(fù)制)。Cython的“記憶視圖”可以高速地在這些結(jié)構(gòu)上進(jìn)行工作,并且具有適合任務(wù)的安全級(jí)別。

Cython C代碼可以從釋放GIL中受益

Python的全局解釋器鎖(Global Interpreter Lock,GIL)同步解釋器中的線程,保護(hù)對(duì)Python對(duì)象的訪問(wèn)并管理資源的爭(zhēng)用。但GIL被廣泛批評(píng)為Python性能的絆腳石,特別是在多核系統(tǒng)上。

如果有一段代碼不會(huì)引用Python對(duì)象并執(zhí)行長(zhǎng)時(shí)間運(yùn)行,那么可以使用nogil:指令將其標(biāo)記為允許它在沒(méi)有GIL的情況下運(yùn)行。這使得Python中間人可以做其他事情,并允許Cython代碼使用多個(gè)內(nèi)核(附加工作)。

Cython可以使用Python類(lèi)型的提示語(yǔ)法

Python有一個(gè)類(lèi)型提示語(yǔ)法,主要由linters和代碼檢查器使用,而不是CPython解釋器。 Cython有它自己的代碼裝飾的自定義語(yǔ)法,但是最近修改了Cython,你可以使用Python類(lèi)型提示語(yǔ)法為Cython提供類(lèi)型提示。

Cython限制

請(qǐng)記住,Cython不是一個(gè)魔術(shù)棒。它不會(huì)自動(dòng)將每一個(gè)poky Python代碼變成極速的C代碼。為了充分利用Cython,你必須明智地使用它,并理解它的局限性:

常規(guī)Python代碼的加速很少

當(dāng)Cython遇到Python代碼時(shí),它不能完全翻譯成C語(yǔ)言,它將這些代碼轉(zhuǎn)換成一系列對(duì)Python內(nèi)部的C調(diào)用。這相當(dāng)于將Python的解釋器從執(zhí)行循環(huán)中提取出來(lái),這使得代碼默認(rèn)加速了15%到20%。請(qǐng)注意,這是最好的情況。在某些情況下,可能看不到性能改善,甚至性能下降。

原生Python數(shù)據(jù)結(jié)構(gòu)有一點(diǎn)加速

Python提供了大量的數(shù)據(jù)結(jié)構(gòu) - 字符串,列表,元組,字典等等。它們對(duì)于開(kāi)發(fā)者來(lái)說(shuō)非常方便,而且他們自帶了自動(dòng)內(nèi)存管理功能,但是他們比純C慢。

Cython讓你繼續(xù)使用所有的Python數(shù)據(jù)結(jié)構(gòu),盡管沒(méi)有太多的加速。這又是因?yàn)镃ython只是在Python運(yùn)行時(shí)調(diào)用創(chuàng)建和操作這些對(duì)象的C API。因此,Python數(shù)據(jù)結(jié)構(gòu)的行為與Cython優(yōu)化的Python代碼大致相同:有時(shí)會(huì)得到一個(gè)提升,但只有一點(diǎn)。

Cython代碼運(yùn)行速度最快時(shí),“純C”

如果你在C中有一個(gè)標(biāo)有cdef關(guān)鍵字的函數(shù),那么它的所有變量和內(nèi)聯(lián)函數(shù)調(diào)用都是純C的,所以它的運(yùn)行速度可以和C一樣快。 但是,如果該函數(shù)引用任何Python原生代碼(如Python數(shù)據(jù)結(jié)構(gòu)或?qū)?nèi)部Python API的調(diào)用),則該調(diào)用將成為性能瓶頸。

幸運(yùn)的是,Cython提供了一種方法來(lái)發(fā)現(xiàn)這些瓶頸:一個(gè)源代碼報(bào)告,一目了然地顯示您的Cython應(yīng)用程序的哪些部分是純C以及哪些部分與Python交互。 對(duì)應(yīng)用程序進(jìn)行了更好的優(yōu)化,就會(huì)減少與Python的交互。

為Cython應(yīng)用程序生成的源代碼報(bào)告。 白色區(qū)域純C;黃色區(qū)域顯示與Python內(nèi)部的交互。一個(gè)精心優(yōu)化的Cython程序?qū)⒈M可能的黃色。 展開(kāi)的最后一行顯示了解釋其相應(yīng)Cython代碼的C代碼。

Cython NumPy

Cython改進(jìn)了基于C的第三方數(shù)字運(yùn)算庫(kù)(如NumPy)的使用。由于Cython代碼編譯為C,它可以直接與這些庫(kù)進(jìn)行交互,并將Python的瓶頸帶出循環(huán)。

但是NumPy特別適用于Cython。 Cython對(duì)NumPy中的特定結(jié)構(gòu)具有本地支持,并提供對(duì)NumPy數(shù)組的快速訪問(wèn)。在傳統(tǒng)的Python腳本中使用的熟悉的NumPy語(yǔ)法可以在Cython中使用。

但是,如果要?jiǎng)?chuàng)建Cython和NumPy之間最接近的綁定,則需要使用Cython的自定義語(yǔ)法進(jìn)一步修飾代碼。例如,cimport語(yǔ)句允許Cython代碼在編譯時(shí)在庫(kù)中查看C級(jí)構(gòu)造,以實(shí)現(xiàn)最快的綁定。

由于NumPy被廣泛使用,Cython支持NumPy“開(kāi)箱即用”。如果你安裝了NumPy,你可以在你的代碼中聲明cimport numpy,然后添加進(jìn)一步的裝飾來(lái)使用暴露的函數(shù)。

Cython分析和性能

可以通過(guò)分析代碼并親眼目睹瓶頸在哪里獲得最佳性能。Cython為Python的cProfile模塊提供鉤子,因此可以使用Python自己的分析工具來(lái)查看Cython代碼的執(zhí)行情況。無(wú)需在工具組之間切換;可以繼續(xù)所熟悉和喜愛(ài)的Python世界中工作。

它有助于記住所有情況下,Cython不是魔術(shù),仍然適用明智的現(xiàn)實(shí)世界的表現(xiàn)實(shí)踐。在Python和Cython之間來(lái)回穿梭越少,你的應(yīng)用運(yùn)行得越快。

例如,如果你有一個(gè)你想要在Cython中處理的對(duì)象的集合,那么不要在Python中迭代它,并且在每一步調(diào)用一個(gè)Cython函數(shù)。將整個(gè)集合傳遞給你的Cython模塊并在那里迭代。這種技術(shù)經(jīng)常在管理數(shù)據(jù)的庫(kù)中使用,因此這是在自己的代碼中模擬的好模型。

我們使用Python是因?yàn)樗鼮槌绦騿T提供了便利,并且能夠快速開(kāi)發(fā)。有時(shí)程序員的工作效率是以犧牲性能為代價(jià)的。使用Cython,只需要一點(diǎn)點(diǎn)額外的努力就可以給你兩全其美的好處。

上述就是小編為大家分享的cython與python有什么不同了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI