Children of a Lesser Python

  
Saturday, October 15, 2005

許多年以來,人們期望提高程序的性能,嘗試着爲Python創建可選的虛擬機(alternative VM),然而無數次這樣的努力都失敗了。即使我們對那些猶如一隻半死不活的、信奉巫術的部隊一樣仍蹣跚前行着的只完成一半的Python-to-Parrot翻譯項目視而不見,而類似Mamba, Rattlesnake Vyper這些即將被遺忘、有着光鮮名字的項目仍成爲了一個個紀念碑,矗立在追求更好VM性能的道路兩旁。

同時,像pycoreShedSkin一類新近的項目仍以類似於他們前輩的充滿希望和樂觀的態度不斷地進行着發佈。(大概一年前在Blog圈裏發佈得熱熱鬧鬧的pycore至今仍未有一個獨立的發行版本出現,且未見任何動作)

似乎讓Python運行速度快一些要比它看起來還要艱難。在考慮CPython實現的時候你沒必要成爲一個編譯器或者VM設計專家並說什麼“執行X太浪費了,我打賭你執行Y速度會更快些。”問題是這些人十有八九已經試過執行Y了並且在他們撞上南牆之前也許已經利用他們的設計讓80%Python跑起來了。

那道南牆實際上主要就是:80%Python不是Python,因爲大家都使用剩餘20%的某些部分。ShedSkin仍未落入與其他項目一同滅亡的境地的唯一原因就是,他巧妙地迴避了這個問題,並且不是通過自命決不是一種“類PythonPython-like)”語言而做到的。然而,這就有有點像Monty PythonThe Holy Grail的黑色騎士,堅持說他的缺胳臂短腿“只是皮外傷”。換句話說確實如此,但也沒有太大意義。

另一方面,我們注意到可選的VMs實際上實現了Python語言,但並未(在很大程度上來說)試圖在速度上超過CPythonJythonIronPython實際上合理地實現了Python語言的全部形式(complete forms),但是從實際的角度來說它們是不同的平臺。試圖以讓一個應用程序能夠在CPython, Jython,IronPython上面都跑起來爲目標是毫無意義的,所以,在任何情況下只有純Python庫在實現的時候纔是可移植的。

但是,正是非純粹Python庫賦予了(C/J/Iron)Python當前絕大部分的價值!對於數據庫訪問,數字搗弄(number crunching,譯者注:(指電腦)迅速進行大量複雜運算),GUI工具的接口或其他任何數以千計的用途,是C, JavaCLR的庫讓Python變得實用了。CPython主要是一種粘合語言(glue language),用於彙編來自於C庫的程序。而JythonIronPython從某種程度上來說是成功的,因爲他們是用於彙編JavaCLR組件的粘合語言。而且由於他們的價值因素取決於別處,Jython,IronPython無需完全實現CPython的語義,儘管他們在試圖走得近一些。

雖然總的來看我會說IronPython程序的性能是否更好仍存在爭議,IronPython實際上在一些Python程序性能微型基準(Python performance microbenchmarks)上完成了改進。當然,很好的度量這個仍是困難的,因爲IronPython是不同的平臺。例如,一個使用NumPy的大批量數字搗弄程序將不會在IronPython上運行,所以你如何來比較它們呢?

這把我們引向了CPython最核心的問題。如果CPython的價值在於今天可以使用它完成所有工作,那麼CPython就要快到提高性能的盡頭了。現在,大多數增強性能的提議都被拒絕了,原因就是他們以向後不兼容(back-incompatible)的方式改變了Pyrhon CAPI。如果一個變化需要每個人都重寫他們的C代碼,這個語言最好不要再是Python了。簡而言之,CPython並不是一個語言實現,與Java VM和庫不同的是,它是一個API平臺,。

我們常常寄希望於Python3000 -- GuidoPython經過徹底思考的大膽想象,無需考慮向後兼容。這裏我們可以告別C API的過去,探索新的領域我們大體是這樣設想的。

然而就在最近,Guido收回了原計劃,例舉了進行中的Perl 6的霧件情況和Joel Spolsky針對重寫旗艦產品的議論(譯者注:霧件指開發完成前就開始作宣傳的產品)。取而代之的是Python 3000變成了Python3.0。這並不是一次完全的重寫,而仍是一個對現有語言進行調整的比較模糊的計劃,摒棄了一些Guido過去認爲是錯誤的東西。儘管將允許向後不兼容,但Guido仍宣稱CPython的實現將不會從頭開始重寫。依舊不清楚的是這是否意味着我們可以通過被重寫的第三方擴展的方式來進行重構。也許,這將取決於具體個案了

但是,正如可提出證據加以證明的那樣,今天對於CPython平臺存在的一個最大的問題就是缺少由語言和Python代碼可表達性定義的一個外部函數(foreign function)接口。取而代之的是CPython總是依靠一個固定的C API來表達外部接口。從最初的想法出發即一個Amoeba操作系統的嵌入式腳本語言--那是沒什麼問題的。但是,缺少C FFI就意味着像SWIG, Pyrex, ctypes, Boost::Python等等這樣的工具得不得不出來彌補這個缺陷,可是他們對於Python來說沒有一個是“標準”。所以一個給定的CPython擴展部分可以用它們中的任何一個或者不用它們來寫。因此,今天便成了向後兼容性的拖累(ball-and-chain)Python/C API

另外,這些工具中很少有被設計成獨立於現有CPython實現的。除了ctypes它們都有可指定一個生成代碼的目標的功能。但是,Python語言定義的FFI將允許CPython API成爲純粹實現的細節,能夠隨一點點結論而改變。實際上,這樣一個FFI具有更大的可移植性,即使對於Jython IronPython也是可用的。

然而,現在要把所有那些都解決爲時已晚,抑或果真如此?

走進PyPy。兩個月前,PyPy0.7發佈了。一個重要的里程碑,PyPy0.7是第一個自足執行(self-hosting)Python實現。它是一個Python的實現,用Python寫的,並可以自行解釋。另外,部分PyPy是一個翻譯系統,它允許將Python代碼翻譯成其他語言,並且包含一種外聯函數接口,雖然託Guido的福仍未被標準化。PyPy開發人員現在已經完成了除了作爲高級Python代碼的C平臺特性的最小化之外重寫的工作。簡而言之,對於我們來說PyPy已經脫離CPython需要向後兼容C API的“引力井”並在這一方面又邁出了重要的一步。

怎麼強調它的重要性也不爲過。當前的CPython實現受困於許多設計決策,而對於PyPy不存在這個問題。舉個簡單的例子,PyPy可以生成本身支持線程和不支持線程的版本,本身的refcounting和垃圾回收的版本等等。本質上講,PyPy關於底層VM是很實際的,即使它使用是CPython的字節碼(bytecode)。所以,在未來幾年裏,VM將有可能在根本上進行重新設計的試驗,而不會像過去的項目一樣在“最後20%的問題”上陷入了困境。哎呀,應該很可能在每個應用程序基礎上都可以使用定製的VMs

另外,由於PyPy是用Python實現的,在它上面進行編程來改變目前的Python語言或者其語義將比在CPython上面編簡單多了。簡而言之,我們幾乎是處於Python語言發展的入門階段,並且正在遠離可選實現(alternative-implementation)這條路。

       但是速度怎麼樣?PyPy目前描述爲比CPython要慢200-300倍,這取決於你正在做什麼和你將它翻譯成什麼樣的VM。這聽起來很糟糕,直到你看到這樣一個事實:在CPython上面運行的、未經翻譯PyPy,在運行的時候要2000倍。這就意味着--如果你注意到--PyPy已經能夠將Python代碼轉換成運行要快10倍的C代碼!

       那是一項很大的改進。應當承認,存在問題的代碼從技術上講是“RPython”。這是一個Python有限子集,其不包含更加動態(more-dynamic)的特性。但是,他無須通過類型聲明來提高速度,就像Pyrex一樣。並且如果Stackless的領導人Christian Tismer能夠在造一個RPython-to-CPython擴展模塊翻譯器的路上繼續走下去,那麼這種技術很快就可以應用到實際中去。

       所以,如果有可能從Python的子集中創建一個高效的C,那是不是意味着PyPy就完結了呢?我們難道就不能執行那個翻譯過程並沿着這條路走下去嗎?很不幸,答案是否定的。當然,雖然我們可以將那些速度快的模塊放回到CPython平臺,翻譯過程仍舊十分緩慢,還需要將其本身進行加速。同樣地,這也仍沒有使CPython真正地快起來這既是意味着我們可以先編譯一些獨立的模塊以使他們運行速度更快一些。

       因而爲了實現所承諾的目標,PyPy必須首先接近CPython的速度。只有當它越來越接近這個目標的時候,越來越多抱有加快程序速度想法的人們就將會對自己說:“我想知道是否可以讓PyPy執行Y而不是X?”並且與現在CPython狀況不同的是,他們用不着既是Python老師也是CPython VM專家纔能有希望實現它。

       所以,新的VM並不會全部涌現出來之後便因其不完善而壽終正寢,取而代之的是,也許我們會很快見到一個相反的趨勢:現存的VM逐漸衰敗,替代它的是始終具備靈活性的PyPy。幸運的話,我們可能還會看到PyPy頂替以CJavaC#作爲翻譯後端的CPython, JythonIronPython的位置,成爲了統治一切的Python平臺(One Python to Rule Them All)。

 

更新:就在我發表這篇文章之後,我聽說了消息,意思是據說到九月份爲止,PyPy已經僅比CPython慢二十倍。如果事實確實如此,形勢發展得實際上更快了。200020020…20.2還有多遠呢(這比CPython還要快5倍)?可不幸的是,每一次數量級新的排序一般會比過去的更困難。糟糕的是他們不能將輸出反饋給回輸入並使其達到到它們想要的高達原來十倍的速度。:)

 

(原文鏈接網址:http://dirtsimple.org/2005/10/children-of-lesser-python.html

 

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