Python 現(xiàn)在已經(jīng)不僅僅是膠水腳本語言了. 不信,?看看下面使用Python的成功案例: - YouTube - 主要由 Python編寫
- NASA
- Industrial Light & Magic Runs - 電影公司
- OpenStack
- Sage - 科學(xué)軟件及其他 (SciPy, PythonXY)
- WEB框架 Django, Pyramid, bottle...
- 修訂控制系統(tǒng)
- 其他不錯(cuò)的軟件
要是你正在尋找快速介紹美麗的Python語言,,我推薦My-Favorite-Python-Things 高級(jí)語言是主流 目前高級(jí)語言可以寫出簡單具有靈活性的代碼. 所以在快速創(chuàng)建應(yīng)用程序的時(shí)候是一個(gè)不錯(cuò)的選擇, 你不需要花時(shí)間來處理各種數(shù)據(jù)類型 (所有接口示例代碼都是為了滿足編譯處理). 可能有些人就會(huì)爭論了,這個(gè)特性會(huì)產(chǎn)生有bug的代碼. 但是 Guido van Rossum說:“生產(chǎn)的代碼誰會(huì)不經(jīng)過測試呢”? 靜態(tài)語言在編譯時(shí)期就能處理一些錯(cuò)誤. 但這并不能檢測出所有的錯(cuò)誤. 最后你還是得編寫測試代碼,。 而有這個(gè)時(shí)間完全可以為動(dòng)態(tài)語言寫出測試代碼. 此外人們還不能設(shè)計(jì)一個(gè)堪稱完美的類型系統(tǒng). 對(duì)此Jim Treavor寫了一些總結(jié),。 新技術(shù)允許我們?yōu)閯?dòng)態(tài)語言設(shè)計(jì)一個(gè)高效的運(yùn)行環(huán)境 (JavaScript V8, LuaJIT, Racket, Common Lisp...), 這也可以和大型的框架競爭 (JVM, .NET, ...) 所有這一切都使得高級(jí)語言越來越流行得在大型企業(yè)和日常生活中使用。 Python能延續(xù)傳奇嗎,? 現(xiàn)在Python非常流行,,同時(shí)它的地位也受到競爭者的挑戰(zhàn)。Python有良好的生態(tài)系統(tǒng),,也有大型軟件和社區(qū)支持,,但它缺乏其競爭者的高效和先進(jìn)的運(yùn)行環(huán)境。 Python 作為膠水語言. 正如我在開頭說的一個(gè)特點(diǎn),,Python很容易連接各種編譯庫,,這是它作為膠水語言在20年前流行的重要原因。但是目前依然活躍的工具已經(jīng)很老舊了,,你必須花大量精力才能使用它們,。 - ctypes
- c 擴(kuò)展 是邪惡的. 它們綁定到Python的特定版本還不能被重復(fù)使用. 更糟糕的是, CPython2和CPython3的c 擴(kuò)展 API不一樣. 想想將庫移植到Python3會(huì)是什么情況吧!
- Cython - 這是被設(shè)計(jì)用來編寫C擴(kuò)展的. 但是我敢確定,,使用C擴(kuò)展是你最后想做的事. Cython 是一個(gè)需要編譯的外部工具. 它最終的代碼并沒有動(dòng)態(tài)行為,,但是它的語法還需要學(xué)習(xí). Cython不支持類型推斷. 使用Cpython你不得不去編譯. Cython也不是一個(gè)標(biāo)準(zhǔn). 它不能作為解釋代碼來執(zhí)行. _nuitka_的作者 Kay Hayen在Static Compilation - That is the point總結(jié)的非常好.
- swig, boost - 這些是非常容易的, 通常修改下C/C++ 代碼就可以了, 或者寫一些方案文件.
相比之下,有很多新的工具能在相同的性能下(甚至超出),,更好的處理這些任務(wù),。 - cffi - 一個(gè)能輕松處理你的c庫的包。在接觸硬件或者支持其他軟件時(shí)你會(huì)經(jīng)常做這樣的事(像數(shù)據(jù)庫客戶端,、驅(qū)動(dòng)程序),。嘗試下在python里使用它是多么簡單吧。你不需要寫任何的封裝,,類型化代碼,。而且還有 CPython 和 PyPy 的支持。
- bitey
將Python作為你代碼的核心 - 膠水語言另一面 膠水語言也有另一面,。我們來想想底層高性能編程的過程,。可能看起來會(huì)是下面幾個(gè)過程: - 構(gòu)思
- 很多復(fù)雜的底層代碼和組織機(jī)構(gòu)代碼,。很可能是一堆晦澀的泛型代碼(為了重用性),。
- 編寫膠水語言
- 編譯
- 運(yùn)行
- 極可能會(huì)做很多的調(diào)試,然后回去修改,,考慮到有這么多的底層代碼,。
感謝Python的簡便性、腳本語言的本質(zhì)和大量的工具,,將他作為你代碼的模板和核心,。這就意味著你只需要寫最少的底層代碼,,讓Python做剩下的事:生成組織代碼和你的底層代碼需要的環(huán)境。 這與以往Lisp的理念一樣,,代碼即數(shù)據(jù),,代碼能夠被其他正在執(zhí)行的代碼理解(代碼可以作為數(shù)據(jù)被處理)。因而機(jī)器可以理解運(yùn)行時(shí)正在執(zhí)行的代碼,,并且去優(yōu)化它,,通過通常的方式就能得到全部的數(shù)據(jù)信息,而不用像C++那樣使用模板,。這是C++和其他流行的編程語言所沒有的,。最終我們有相對(duì)更底層的抽象級(jí)別,而運(yùn)行時(shí)信息相對(duì)更豐富,,使得編譯器可以: - 為未知的硬件做特化 (編碼時(shí)),,包括支持的數(shù)據(jù)類型,以及可用的優(yōu)化方法,。
- 自動(dòng)調(diào)整(tuning) (例如為庫提供的數(shù)據(jù),,如 ATLAS...)
- 推送更多的信息給編譯器,得到更好的推理,。
- 人們不用為數(shù)據(jù)類型煩惱(運(yùn)行時(shí)環(huán)境就已經(jīng)可以保證快速,、正確使用數(shù)據(jù)類型)
于是整個(gè)流程就好像這樣: - 想法
- 一點(diǎn)Python代碼(最棒的部分),用來構(gòu)建整個(gè)架構(gòu),。然后是一些底層的代碼 ,,同樣很棒,因?yàn)檫@些代碼沒有惡心的模板和上下文代碼,。事實(shí)上,,底層的代碼也可以通過Python代碼生成。
- 運(yùn)行
- 調(diào)試,,比起前面的步驟時(shí)間更短一些
就性能而言,,這樣的過程相比之前的方法有著更好的前景。 這些是已經(jīng)用到這種方式的:PyPy, cffi, PyOpenCL, PyCUDA, numba, theano... 把Python當(dāng)做一個(gè)高速語言 有很多方法能用Python寫出高速的代碼,。最流行而且仍在廣泛傳播的方法是,,用底層語言來寫應(yīng)用里最復(fù)雜的部分,然后使用,,這對(duì)python來說無疑是很不幸的事,。 所有Python里出色的高效的工具都需要許多復(fù)雜的c代碼,這阻礙了其他的貢獻(xiàn)者進(jìn)來?,F(xiàn)在我們想要寫出高速而且美觀的python代碼,。 有很多工具可以把python代碼編譯成機(jī)器代碼,,比如:Nuitka, Python2C, Shedskin, pythran,。我認(rèn)為它們都是失敗的,,當(dāng)你使用它們的時(shí)候,就需要跟動(dòng)態(tài)行為說再見了,。他們只支持一部分的python語言,,并且離完全支持還有很大距離。我甚至不認(rèn)為以后他們能做到,。另外他們也沒有用那些使JIT(Just-In-Time 運(yùn)行時(shí)編譯執(zhí)行)的解決方案變得出色的先進(jìn)的技術(shù)和運(yùn)行時(shí)信息,。 多核編程 這方面,Armins Rigo的文章寫的很棒,,可以參考:Multicore Programming in PyPy and CPython 解釋器的設(shè)計(jì) 為了讓下一步的開發(fā)更簡單,,實(shí)現(xiàn)動(dòng)態(tài)語言的最佳狀態(tài),Python需要一個(gè)合適的架構(gòu),。當(dāng)前CPython的架構(gòu)過于簡單,,因而限制比較大,很難做到像JIT編譯器那樣的功能,。下面是一些在增強(qiáng)CPython解釋器性能上的失敗的努力: - psyco (被PyPy代替)
- Unladen swallow
- 消除GIL的很多失敗的嘗試
- 還有一些嘗試修復(fù)CPython一些缺陷的嘗試: Stackless和HotPy,,但是Guido (Python之父,仁慈的獨(dú)裁者) 的堅(jiān)持使得這些項(xiàng)目沒有被合并到Python中,。(說明一下,,HotPy還不是產(chǎn)品級(jí)的東西)。
CPython最大的問題是他的C API,,這部分沒有很好的設(shè)計(jì),。其他部分的實(shí)現(xiàn)多少都受此影響。 我們能做什么,?- 在粘結(jié)代碼中推進(jìn)新工具的使用 ( cffi, bitey)
- 在公共庫中停止對(duì)CPython的底層屬性(C API,,C擴(kuò)展)的依賴。作為替代,,采用有如下功能的中間工具:
- cffi - 簡化對(duì)C庫的應(yīng)用
- cython - 編寫可移植的C擴(kuò)展,。我并不推薦它用于通常的編程,不過它確實(shí)在維護(hù)C擴(kuò)展方面更好一些,,也更簡單,。Cython已經(jīng)有CPython和PyPy后端。
為何 PyPy 是趨勢(shì),? PyPy為優(yōu)化和進(jìn)一步的語言開發(fā)提供了更好的架構(gòu),。對(duì)于大部分Python已有的問題,PyPy已經(jīng)提供了解決方案: - 先進(jìn)的runtime和設(shè)計(jì),,在此文中作了介紹: The Architecture of Open Source Applications.
- 速度 - PyPy內(nèi)置的JIT很棒,,有時(shí)(其實(shí)很少)甚至可以與C相提并論。
- GIL問題 - PyPy引入了一個(gè)很棒的STM實(shí)現(xiàn),在 Armins Rigo的 文章中對(duì)此作了介紹,。
- 粘合代碼 - 使用cffi可以簡單的處理C庫,,甚至比CPython的ctypes還要快!
- 異步編程,。這方面,,PyPy內(nèi)置的 greenlet 比CPython的C擴(kuò)展更適合一些。實(shí)際上,,非堆棧式的概念(也即greenlet)在PyPy中還在繼續(xù)發(fā)展(參看https://ep2012./conference/talks/the-story-of-stackless-python)
- 沙盒技術(shù)
- 應(yīng)用在web和移動(dòng)中,。這里有Dusty的一些文章:Pushing Python Past the Present
PyPy已經(jīng)支持多平臺(tái) (x86, 64_x86, ARM) PyPy同時(shí)還包含了一個(gè)優(yōu)秀的現(xiàn)代的架構(gòu),在 Jim Huang 的演講 中做了介紹,,演講的要點(diǎn)是: - 解釋性語言的框架
- 用于研究和產(chǎn)品的組件組合 (不同的數(shù)據(jù)模型,,垃圾回收 - 這些可以在具體的應(yīng)用場景進(jìn)行改變)
- 構(gòu)建在基于組件鏈的功能架構(gòu)之上(翻譯工具鏈)。每一個(gè)步驟都會(huì)延續(xù)/轉(zhuǎn)換程序模型,、引入特征,、各種后端(JVM, JavaScript, LLVM, GCC IR等等)。來看一下翻譯鏈的例子:python 代碼 -> 字節(jié)碼 -> 函數(shù)對(duì)象 -> 類型推斷 -> 垃圾收集器 -> JIT
- 包含大量在架構(gòu)的不同層次開發(fā)的現(xiàn)代的優(yōu)化技術(shù) (這個(gè)任務(wù)可以簡化)
相信讓所有軟件支持PyPy需要付出艱巨的努力 - 需要在現(xiàn)有的庫上做很多工作,。不過使用新的工具,,編寫支持PyPy和CPython的軟件會(huì)比采用C擴(kuò)展的方式更簡單一些(在我們能做什么一節(jié)有介紹)。 CPython遺留問題 現(xiàn)在來說一下CPython依賴性代碼的遺留問題 (源于它們緊密依賴 c 擴(kuò)展),。 這些主要是科學(xué)相關(guān)的軟件 (NumPy, SciPy 等等),。Python在PyPy成為產(chǎn)品級(jí)軟件之前早就被用于科學(xué)計(jì)算(我認(rèn)為實(shí)在2年之前),之后這些軟件在工具,、代碼和社區(qū)方面都得到很多發(fā)展,。這些軟件一起構(gòu)建了一個(gè)很棒的平臺(tái),通常被用來作為Matlab之類的軟件的替換(有人甚至認(rèn)為是更好的選擇),。要實(shí)現(xiàn)這些,,C擴(kuò)展是目前唯一的解決方案。現(xiàn)在,,這些軟件的發(fā)展仍然與CPython緊密綁定,,因?yàn)橐尶茖W(xué)計(jì)算相關(guān)的軟件全部支持PyPy,需要大量的工作,。近似的方案是使用按需執(zhí)行的JIT - 對(duì)特定的函數(shù)做修飾,,然后動(dòng)態(tài)的把它們編譯成機(jī)器碼并切換到使用c擴(kuò)展。這個(gè)想法不需要重寫所有的科學(xué)計(jì)算的平臺(tái),,而速度同樣快速,。采用這種方式的典型項(xiàng)目是numba,這是由Continuum Analytics (這家公司主要發(fā)布基于python庫的強(qiáng)壯的科學(xué)計(jì)算平臺(tái))贊助的,。Numba采用這種方式是因?yàn)樗目焖倌_本需要與其他依賴CPython的科學(xué)計(jì)算代碼兼容,。numba值得學(xué)一下,,SciPy會(huì)議的 numba演講 是一個(gè)很好的闡述。 不得不說Python的科學(xué)計(jì)算社區(qū)非常棒,。他們非常關(guān)注于質(zhì)量,、易用性和推廣他們的產(chǎn)品(為此組織了很多會(huì)議:SciPy大會(huì),PyData等),。感謝他們讓Python成為免費(fèi)的科學(xué)分析平臺(tái)的首選。這里還需要提一下Travis Oliphant,,他在社區(qū)中付出了很多努力,,讓整個(gè)平臺(tái)協(xié)調(diào)一致。關(guān)于這些可以看一下這篇博客文章:為何Python是你最終必須學(xué)習(xí)的編程語言 PyPy呢? 我希望PyPy當(dāng)時(shí)并沒有達(dá)到產(chǎn)品級(jí)可用,。 后續(xù) 關(guān)于本文的后續(xù)在Reddit上有一個(gè)有趣的討論,。這是關(guān)于在商業(yè)上應(yīng)用PyPy的優(yōu)缺點(diǎn)的討論。討論者總結(jié)了如何使用基于高性能庫的PyPy,。最重要的是使用PyPy軟件棧(原始Python,、cffi,等等)可以讓維護(hù)和優(yōu)化很簡單(例如:延遲計(jì)算),。至于缺點(diǎn),,上面提到了,主要與CPython的遺留問題有關(guān),。 |