一、Python運行速度慢的原因
1、python是解釋性語言
python是一個解釋性的動態類型腳本語言,解釋性語言的特點就是程序只有在執行的時候才會去編譯,也就是說邊執行邊進行編譯。而Java、C這種編譯性的語言在程序執行之前就已經將其編譯為機器可讀的代碼了,自然運行速度快。而且python程序在沒有運行之前都是能夠直接以源碼的形式存在的,這也是它能夠跨平臺運行的主要原因,但是在沒有經過編譯的python運行速度上就會有所降低。
2、Python是動態語言
動態語言是一類在運行時可以改變其結構的語言,如新的函數、對象、代碼可以被引入,已有的函數可以被刪除或其他結構上的變化等,該類語言更具有活性,但是不可避免的因為運行時的不確定性也影響運行效率。數據的比較和轉換類型的開銷很大,每次讀取、寫入或引用一個變量,都要檢查類型。很難優化一種極具動態性的語言。Python的許多替代語言之所以快得多,原因在于它們為了性能在靈活性方面作出了犧牲。
3、Python中一切都是對象
Python是一門面向對象的編程語言,其設計理念是一切皆是對象,如數字、字符串、元組、列表、字典、函數、方法、類、模塊等都是對象,包括代碼,每個對象都需要維護引用計數,因此,增加了額外工作,影響了性能。
4、Python GIL
GIL是Python最為詬病的一點,因為GIL,Python中的多線程并不能真正的并發,即使在單線程,GIL也會帶來很大的性能影響,因為python每執行100個opcode就會嘗試線程的切換,因此,影響Python運行效率。
5、垃圾回收機制
Python采用標記和分代的垃圾回收策略,每次垃圾回收的時候都會中斷正在執行的程序,造成所謂的頓卡,影響運行效率。
二、提升Python性能的方案
1、Cython
是Python的C語言擴展,cPython是一門單獨的語言,專門用來寫在Python里面的import用的擴展庫。CPython跟Python語法基本一致,而CPython有專門的編譯器。據說,Cython提供了一些特性來讓代碼更高效,比如變量類型化,這本質上是C要求的。一些科學計算的包,如scikit-learn依賴Cython的一些特性來保持操作簡潔快速。
2、Pyston
Pyston,由Dropbox資助,使用LLVM編譯器架構來加速Python,同樣的它也使用了適時編譯。相比于PyPy,Pyston還處于早期階段,它只支持Python的部分特性。Pyston把工作分成兩個部分,一部分是語言的核心特性,另一部分是把性能提升到可接受的程度。Pyston距離可以在生產環境使用還有一段距離
3、Nuitka
是一個Python的替代品,它可以將Python代碼轉換為C++代碼,然后編譯為可執行文件,并且通過調用Python的API的方式實現從解析語言到編譯語言的轉換,在轉換到C++的過程中直接使用python的解釋器,可以保證100%的語法兼容。
4、Numba
Numba結合了上面幾個項目的想法。學習了Cython,Numba也采用了部分加速的策略,只加速CPU密集型的任務;同時它又學習了PyPy和Pyston,通過LLVM運行Python。你可以用一個裝飾器指定你要用Numba編譯的函數,Numba繼承Numpy來加速函數的執行,Numba不做適時編譯,它的代碼是預先編譯的。
5、PyPy
在選擇CPython的簡易替代語言時,pypy無疑時優異之選,與現有Python代碼保持高度兼容性,pypy也是默認程序運行時的一個很好選擇。PyPy使用了Just-in-Time即時編譯器,動態編譯器與靜態編譯器不同,利用程序運行的過程的數據進行優化。
PyPy使用適時編譯來加速Python,這項技術Google也在使用,Google在V8引擎中使用它加速Javascript。最近的版本PyPy2.5增加了一些提升性能的特性,其中有一項很受歡迎,它集成了Numpy,Numpy之前也一直被用來加速Python的運行。
延伸閱讀1:Python優勢
Python最大的優勢在于效率。有時候程序員或科研工作者的效率比機器的效率更重要,對于很多復雜性的功能,使用更加清晰的語言能給程序減少更多的負擔,從而大大增強程序的質量,其易學性和擴展性也能讓新手很快上手。雖然Python底層運行速度要比C語言慢,但Python清晰的結構能解放程序員的時間,同時很方便的和其他編程語言代碼(如C語言)融合在一起。