訂閱
糾錯
加入自媒體

Python狀況:為什么PyPy是Python的未來?

2019-01-19 10:09
python猿
關注

Python 現(xiàn)在已經(jīng)不僅僅是膠水腳本語言了,不信?看看下面使用Python的成功案例:

YouTube - 主要由 Python編寫

NASA

Industrial Light & Magic Runs - 電影公司

OpenStack

Sage - 科學軟件及其他 (SciPy, PythonXY)

WEB框架 Django, Pyramid, bottle......

修訂控制系統(tǒng)

其他不錯的軟件

要是你正在尋找快速介紹美麗的Python語言,我推薦My-Favorite-Python-Things

高級語言是主流

目前高級語言可以寫出簡單具有靈活性的代碼,所以在快速創(chuàng)建應用程序的時候是一個不錯的選擇, 你不需要花時間來處理各種數(shù)據(jù)類型 (所有接口示例代碼都是為了滿足編譯處理),可能有些人就會爭論了,這個特性會產(chǎn)生有bug的代碼, 但是 Guido van Rossum說:“生產(chǎn)的代碼誰會不經(jīng)過測試呢”? 靜態(tài)語言在編譯時期就能處理一些錯誤,但這并不能檢測出所有的錯誤, 最后你還是得編寫測試代碼。 而有這個時間完全可以為動態(tài)語言寫出測試代碼,此外人們還不能設計一個堪稱完美的類型系統(tǒng),對此Jim Treavor寫了一些總結。

新技術允許我們?yōu)閯討B(tài)語言設計一個高效的運行環(huán)境 (JavaScript V8, LuaJIT, Racket, Common Lisp...), 這也可以和大型的框架競爭 (JVM, NET, ...)

所有這一切都使得高級語言越來越流行得在大型企業(yè)和日常生活中使用。

Python能延續(xù)傳奇嗎?

現(xiàn)在Python非常流行,同時它的地位也受到競爭者的挑戰(zhàn)。Python有良好的生態(tài)系統(tǒng),也有大型軟件和社區(qū)支持,但它缺乏其競爭者的高效和先進的運行環(huán)境。

Python 作為膠水語言

正如我在開頭說的一個特點,Python很容易連接各種編譯庫,這是它作為膠水語言在20年前流行的重要原因。但是目前依然活躍的工具已經(jīng)很老舊了,你必須花大量精力才能使用它們。

ctypes

c 擴展是邪惡的, 它們綁定到Python的特定版本還不能被重復使用, 更糟糕的是, CPython2和CPython3的c 擴展 API不一樣,想想將庫移植到Python3會是什么情況吧!

Cython - 這是被設計用來編寫C擴展的,但是我敢確定,使用C擴展是你最后想做的事,Cython 是一個需要編譯的外部工具, 它最終的代碼并沒有動態(tài)行為,但是它的語法還需要學習,Cython不支持類型推斷,使用Cpython你不得不去編譯, Cython也不是一個標準, 它不能作為解釋代碼來執(zhí)行_nuitka_的作者 Kay Hayen在Static Compilation - That is the point總結的非常好。

swig, boost - 這些是非常容易的, 通常修改下C/C++ 代碼就可以了, 或者寫一些方案文件。

相比之下,有很多新的工具能在相同的性能下(甚至超出),更好的處理這些任務。

cffi - 一個能輕松處理你的c庫的包。在接觸硬件或者支持其他軟件時你會經(jīng)常做這樣的事(像數(shù)據(jù)庫客戶端、驅動程序)。嘗試下在python里使用它是多么簡單吧。你不需要寫任何的封裝,類型化代碼。而且還有 CPython 和 PyPy 的支持。

bitey

將Python作為你代碼的核心 - 膠水語言另一面

膠水語言也有另一面。我們來想想底層高性能編程的過程?赡芸雌饋頃窍旅鎺讉過程:

構思

很多復雜的底層代碼和組織機構代碼。很可能是一堆晦澀的泛型代碼(為了重用性)。

編寫膠水語言

編譯

運行

極可能會做很多的調試,然后回去修改,考慮到有這么多的底層代碼。

感謝Python的簡便性、腳本語言的本質和大量的工具,將他作為你代碼的模板和核心。這就意味著你只需要寫最少的底層代碼,讓Python做剩下的事:生成組織代碼和你的底層代碼需要的環(huán)境。

這與以往Lisp的理念一樣,代碼即數(shù)據(jù),代碼能夠被其他正在執(zhí)行的代碼理解(代碼可以作為數(shù)據(jù)被處理)。因而機器可以理解運行時正在執(zhí)行的代碼,并且去優(yōu)化它,通過通常的方式就能得到全部的數(shù)據(jù)信息,而不用像C++那樣使用模板。這是C++和其他流行的編程語言所沒有的。最終我們有相對更底層的抽象級別,而運行時信息相對更豐富,使得編譯器可以:

為未知的硬件做特化 (編碼時),包括支持的數(shù)據(jù)類型,以及可用的優(yōu)化方法。

自動調整(tuning) (例如為庫提供的數(shù)據(jù),如 ATLAS...)

推送更多的信息給編譯器,得到更好的推理。

人們不用為數(shù)據(jù)類型煩惱(運行時環(huán)境就已經(jīng)可以保證快速、正確使用數(shù)據(jù)類型)

于是整個流程就好像這樣:

想法

一點Python代碼(最棒的部分),用來構建整個架構。然后是一些底層的代碼 ,同樣很棒,因為這些代碼沒有惡心的模板和上下文代碼。事實上,底層的代碼也可以通過Python代碼生成。

運行

調試,比起前面的步驟時間更短一些

就性能而言,這樣的過程相比之前的方法有著更好的前景。

這些是已經(jīng)用到這種方式的:PyPy, cffi, PyOpenCL, PyCUDA, numba, theano...

把Python當做一個高速語言

有很多方法能用Python寫出高速的代碼。最流行而且仍在廣泛傳播的方法是,用底層語言來寫應用里最復雜的部分,然后使用,這對python來說無疑是很不幸的事。

所有Python里出色的高效的工具都需要許多復雜的c代碼,這阻礙了其他的貢獻者進來,F(xiàn)在我們想要寫出高速而且美觀的python代碼。

有很多工具可以把python代碼編譯成機器代碼,比如:Nuitka, Python2C, Shedskin, pythran。我認為它們都是失敗的,當你使用它們的時候,就需要跟動態(tài)行為說再見了。他們只支持一部分的python語言,并且離完全支持還有很大距離。我甚至不認為以后他們能做到。另外他們也沒有用那些使JIT(Just-In-Time 運行時編譯執(zhí)行)的解決方案變得出色的先進的技術和運行時信息。

多核編程

這方面,Armins Rigo的文章寫的很棒,可以參考:Multicore Programming in PyPy and CPython

解釋器的設計

為了讓下一步的開發(fā)更簡單,實現(xiàn)動態(tài)語言的最佳狀態(tài),Python需要一個合適的架構。當前CPython的架構過于簡單,因而限制比較大,很難做到像JIT編譯器那樣的功能。下面是一些在增強CPython解釋器性能上的失敗的努力:

psyco (被PyPy代替)

Unladen swallow

消除GIL的很多失敗的嘗試

還有一些嘗試修復CPython一些缺陷的嘗試: Stackless和HotPy,但是Guido (Python之父,仁慈的獨裁者) 的堅持使得這些項目沒有被合并到Python中。(說明一下,HotPy還不是產(chǎn)品級的東西)。

CPython最大的問題是他的C API,這部分沒有很好的設計。其他部分的實現(xiàn)多少都受此影響。

我們能做什么?

在粘結代碼中推進新工具的使用 ( cffi, bitey)

在公共庫中停止對CPython的底層屬性(C API,C擴展)的依賴。作為替代,采用有如下功能的中間工具:

cffi - 簡化對C庫的應用

cython - 編寫可移植的C擴展。我并不推薦它用于通常的編程,不過它確實在維護C擴展方面更好一些,也更簡單。Cython已經(jīng)有CPython和PyPy后端。

為何 PyPy 是趨勢?

PyPy為優(yōu)化和進一步的語言開發(fā)提供了更好的架構。對于大部分Python已有的問題,PyPy已經(jīng)提供了解決方案:

先進的runtime和設計,在此文中作了介紹: The Architecture of Open Source Applications。

速度 - PyPy內(nèi)置的JIT很棒,有時(其實很少)甚至可以與C相提并論。

GIL問題 - PyPy引入了一個很棒的STM實現(xiàn),在 Armins Rigo的 文章中對此作了介紹。

粘合代碼 - 使用cffi可以簡單的處理C庫,甚至比CPython的ctypes還要快!

異步編程。這方面,PyPy內(nèi)置的 greenlet 比CPython的C擴展更適合一些。實際上,非堆棧式的概念(也即greenlet)在PyPy中還在繼續(xù)發(fā)展。

沙盒技術

應用在web和移動中。這里有Dusty的一些文章:Pushing Python Past the Present

PyPy已經(jīng)支持多平臺 (x86, 64_x86, ARM)

PyPy同時還包含了一個優(yōu)秀的現(xiàn)代的架構,在 Jim Huang 的演講 中做了介紹,演講的要點是:

解釋性語言的框架

用于研究和產(chǎn)品的組件組合 (不同的數(shù)據(jù)模型,垃圾回收 - 這些可以在具體的應用場景進行改變)

構建在基于組件鏈的功能架構之上(翻譯工具鏈)。每一個步驟都會延續(xù)/轉換程序模型、引入特征、各種后端(JVM, JavaScript, LLVM, GCC IR等等)。來看一下翻譯鏈的例子:python 代碼 -> 字節(jié)碼 -> 函數(shù)對象 -> 類型推斷 -> 垃圾收集器 -> JIT

包含大量在架構的不同層次開發(fā)的現(xiàn)代的優(yōu)化技術 (這個任務可以簡化)

相信讓所有軟件支持PyPy需要付出艱巨的努力 - 需要在現(xiàn)有的庫上做很多工作。不過使用新的工具,編寫支持PyPy和CPython的軟件會比采用C擴展的方式更簡單一些。

聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號