讓Python代碼更快運行的 5 種方法

2021-02-21 Qunar技術沙龍

文章出處: IT168 翻譯,點擊文章底部「閱讀原文」查看更多精彩技術、資訊內容

不論什麼語言,我們都需要注意性能優化問題,提高執行效率。選擇了腳本語言就要忍受其速度,這句話在某種程度上說明了Python作為腳本語言的不足之處,那就是執行效率和性能不夠亮。儘管Python從未如C和Java一般快速,但是不少Python項目都處於開發語言領先位置。

Python很簡單易用,但大多數人使用Python都知道在處理密集型cpu工作時,它的數量級依然低於C、Java和JavaScript。但不少第三方不願贅述Python的優點,而是決定自內而外提高其性能。如果你想讓Python在同一硬體上運行得更快,你有兩個基本選擇,而每個都會有一個缺點:

·您可以創建一個默認運行時所使用的替代語言(CPython的實現)——一個主要的任務,但它最終只會是CPython的一個簡易替代者。

·您也可以利用某些速度優化器重寫現有Python代碼,這意味著程式設計師要花更多精力編寫代碼,但不需要在運行時加以改變。

如何進行Python性能優化,是本文探討的主題。下面是五個方法可以在某些方面提高Python代碼的性能和執行效率。

PyPy

在選擇CPython的簡易替代語言時,PyPy無疑是最佳之選(如Quora就是由它編寫而成)。由於與現有Python代碼保持高度兼容性,PyPy也是默認程序運行時的一個很好選擇。

PyPy使用了Just-in-Time(JIT)即時編譯器,即動態編譯器,與靜態編譯器(如gcc,java等)不同,它是利用程序運行的過程的數據進行優化,擁有同谷歌Chrome V8 JavaScript引擎相同的語言加速技術。本月初,最新版本PyPy 2.5即將發布,此版本會有一系列的性能改進,提供更全面的如NumPy的支持,用於加速Python性能的共享庫。

Python 3.x必須由單獨的PyPy3項目構建而成。不過,對於邊緣語言特性愛好者來說,儘管預期支持3.3,但實際此版本最多僅支持Python3.2.4及以下版本。

相關連結:http://pypy.org/

Pyston

Pyston是一款Dropbox推出的新的基於JIT的Python實現,使用LLVM編譯器實現代碼解析與轉換。與PyPy相比,Pyston仍處於初級階段,目前最新版本為Pyston 0.2版,支持有限子集語言的相關特性。Pyston的主要工作包括支持語言的核心功能及提升關鍵指標性能到一個可接受的水平。不久後,Pyston就可以被認為是遠程生產就緒語言。

相關連結:https://github.com/dropbox/pyston

Nuitka

Nuitka 是一個Python的替代品,一些團隊正用它做完全的Python編譯工具,並嘗試將Python代碼轉譯為其它可高速運行的程式語言。Nuitka(nuitka.net)可以將python代碼轉換為C++代碼,然後編譯為可執行文件,並通過直接調用python的api的方式實現從解析語言到編譯語言的轉換,並且在轉換到C++的過程中直接使用python的解釋器,可以保證100%的語法兼容。雖然這限制了它的可移植性,但不可否認這個轉換的速度獲得了肯定。

相關連結:http://nuitka.net/

Cython

Cython是Python 的C語言擴展。準確說Cython是單獨的一門語言,專門用來寫在Python裡面import用的擴展庫。實際上Cython的語法基本上跟Python一致,而Cython有專門的編譯器:先將 Cython代碼轉變成C(自動加入了一大堆的C-Python API),然後使用C編譯器編譯出最終的Python可調用的模塊。不過Cython的缺點是,你並不能真正編寫Python代碼,這樣一來,現有代碼將不會完全自動轉移成功。

也就是說,Cython在提速方面有很大優勢,它是一個用來快速生成Python擴展模塊(extention module)的工具。而在Cython,C裡的類型,如int,float,long,char*等都會在必要的時候自動轉成python對象,或者從python對象轉成C類型,在轉換失敗時會拋出異常,這正是Cython最神奇的地方。另外,Cython對回調函數的支持也很好。總之,如果你有寫python擴展模塊的需求,那麼Cython真的是一個很好的工具。

相關連結:http://cython.org/

Numba

Numba綜合了前兩種方法,是Cython的競爭項目。同樣的,numba把Python源碼通過LLVMPy生成JIT後的.so文件來加速。不同點在於,Numba是以JIT為主的,加速對源碼的侵入性較小。而Cython則重點在加速高性能Python模塊的開發上,不依賴LLVMPy項目。此外numba還很不成熟,目前兼容性相當差。

相關連結:http://numba.pydata.org/

Python創始人Guido van Rossum堅信Python的許多性能問題可以歸結為語言的使用不當。例如,對於CPU消耗過高的處理,可以通過一些方法來加速Python運行——使用NumPy、使用多處理器擴展、或藉助外部C代碼從而避免全局解釋器鎖(GIL)——Python緩慢的根源。但由於在Python中還沒有可行的GIL替代語言,Python仍將在短期落後於其他語言——甚至可能更長時間。

相關焦點

  • 讓 Python 代碼運行更快的最佳方式!
    但是就語言的設計,也就是它天然的解釋能力還有它的運行時的動態性而言,Python總是比C或C ++這樣的機器本地語言慢一個數量級。多年來,開發人員已經為Python的速度限制提出了各種變通方法。例如你可以在C中編寫性能密集型任務並使用Python封裝它,許多機器學習庫正是這樣做的。
  • 5種方法,加密你的Python代碼
    最常見的加密方式有4種,還有1種獨特的加密方式。1Python解釋器在執行代碼的過程中,會首先生成.pyc文件,然後再解釋執行.pyc中的內容,當然,解釋器也能直接執行.pyc文件。.pyc文件是一個二進位的文件,是不具備可讀性的。假如我們發到客戶環境時,是.pyc文件,而不是.py,那麼是不是就可以保護我們的Python代碼?
  • ​如何使用生成器減少內存佔用,並讓Python代碼運行更快?
    本文轉載自公眾號「讀芯術」(ID:AI_Discovery)如何使用生成器減少內存佔用並讓Python代碼運行更快,關乎你「代碼人生」的生死存亡。 然而,當我剛開始學習Python生成器時,並不知道它最後會顯得如此重要。 但在學習機器學習的過程中需要編寫自定義函數時,它發揮了不可取代的作用。
  • 技能分享:如何用生成器減少內存佔用,讓Python代碼運行更快?
    圖源:Unsplash如何使用生成器減少內存佔用並讓Python代碼運行更快,關乎你「代碼人生」的生死存亡。當調用生成器上的特殊方法,例如next(),函數中的代碼會執行到yield語句。當執行到達了Python代碼中的yield語句,程序就會中止函數的執行,並將產生的值返回給調用方。(相反,return會完全停止函數執行。)當一個函數被掛起時,它的狀態會被保存。
  • 代碼詳解:如何用Python運行高性能的數學範式?
    對於以性能為核心的應用程式和數據處理通道來講,需要運行最佳範例並選擇正確的庫集。那麼,在開發和學習中有哪些技巧呢?首先需要明確的是:編寫python代碼和編寫pythonic代碼之間存在很大差異。,最後會將所有使用timeit庫的運行情況進行比較:1.一種非常簡單和直接的方法是遍歷整個數據集,並將函數f(x)(上面定義)的輸出附加到輸出列表對象。
  • 讓你python代碼更快的3個小技巧
    今天呢,我們來聊一聊如何加速你的 python 代碼。Python 語言的優點可以列舉出許多,語法簡單易懂、模塊豐富、應用廣泛等等。但是世界上沒有有完美的東西,python 一個明顯缺點就是運行速度慢,至少跟 C 語言沒法比。所以,不安於現狀的 Pythoner 就開發了許多工具。其中,最著名的莫過於 Cython 和 Numba。
  • 讓你的Python運行更快
    因此,讓我們證明一些人是錯誤的,讓我們看看如何改善Python程序的性能 並使它們真正更快!時序分析在開始進行任何優化之前,我們首先需要找出代碼的哪些部分實際上會使整個程序變慢。此處的區別是perf_counter返回絕對值,其中包括Python程序進程未運行時的時間,因此它可能會受到計算機負載的影響。另一方面,process_time僅返回用戶時間(不包括系統時間),這僅是您的處理時間。使其更快現在是有趣的部分。讓我們讓您的Python程序運行得更快。我(大部分)不會向您展示一些可以神奇地解決您的性能問題的技巧,技巧和代碼段。
  • 在Rust 代碼中編寫 Python 是種怎樣的體驗?
    運行Python代碼首先,讓我們看一下如何在Rust中運行Python代碼。讓我們嘗試使第一個簡單的示例生效:fn main(){ println!("Hello ..."); run_python("print(\"... World!\")");}我們可以使用std::process::命令來運行python可執行文件並傳遞python代碼,從而實現run_python,但如果我們希望能夠定義和讀回Python變量,那麼最好從使用PyO3庫開始。
  • 如何用iPad運行Python代碼?
    例如乾脆錄製代碼執行視頻給你看。但是正如我在《MOOC教學,什麼最重要?》一文中說過的,學習過程裡,反饋最重要。你需要能運行代碼,並且第一時間獲得結果反饋。在此基礎上,你還得能修改代碼,對比前後執行結果的差別。我得給你提供一個直接可以運行的環境。
  • Python代碼技巧,你值得擁有!
    通過類的repr方法可以將類列印得更易讀。或者不定義repr方法,直接使用下面方式列印:print p.__dict__# {'y': 4, 'x': 3}使用dict方法,將類以字典形式列印出來,也比較易讀。
  • 代碼跑得慢甩鍋Python?手把手教你如何給代碼提速30%
    其實某個特定程序(無論使用何種程式語言)的運行速度是快還是慢,在很大程度上取決於編寫該程序的開發人員自身素質,以及他們編寫優化而高效代碼的能力。Medium上一位小哥就詳細講了講如何讓python提速30%,以此證明代碼跑得慢不是python的問題,而是代碼本身的問題。
  • 八行python代碼展現程式設計師從入門到大神的八種階段
    人生苦短,我用python。python的世界裡無處不在的簡潔和短小,往往一行代碼可以實現很多有意思功能。你敢想像你從入門python代碼、網絡達人、反重力怪才、愛情自由怪、資源盜獵者、頓悟入禪、無所不能或者卷鋪跑路8個狀態只用了簡簡單單的8行代碼嗎?
  • 一行代碼讓你的pandas運行得更快
    但是,當處理過於龐大的數據時,單個內核上運行的 Pandas 就會變得力不從心,人們不得不求助於不同的分布式系統來提高性能。然而,為了提高性能而做的這種權衡會帶來陡峭的學習曲線。本質上,用戶只是想讓 Pandas 運行得更快,而不是為了特定的硬體設置而優化其工作流。這意味著人們希望在處理 10KB 的數據集時,可以使用與處理 10TB 數據集時相同的 Pandas 腳本。
  • Python代碼加速利器:Cython
    有了C編譯器之後,你只需運行:如何使用Cython我們將在IPython中演示Cython。我們首先介紹IPython Magic命令。Magic命令以百分號開頭,通常有2種類型:首先運行下列語句引入Cython:然後,當運行Cython代碼時,我們需要加入以下Cython 代碼:然後就可以愉快地使用Cython了。Cython的速度有多快?Cython 主要優化的是循環與遞歸。讓我們用斐波那契數列來證明這一點。
  • 加快程序運行速度只需一行 Python 代碼
    for _ in range(size):        worker = Consumer(queue)        worker.start()        workers.append(worker)    return workersif __name__ == __main__ :    Producer()這段代碼能正確的運行
  • Python程序的編輯及運行,Pycharm的下載安裝
    Python程序的運行方式:在我這有三種:1、通過命令行(command.exe)運行Python。2、通過Python自帶的IDLE(集成開發環境 integrated development environment)3、PyCharm 一個強大的IDE(集成開發環境 integrated development environment)第一種 命令行運行Python開始菜單- 運行-cmd 按確認後進入命令行
  • 這些方法助力Python開發者提高效率
    你可以在解釋器終端直接運行該函數。 Python 文檔有更多該函數的用法。 5. 使用庫 Python 有大量的庫可以讓你不必每次都重複造輪子。 比如,你可以從 PyPI(Python包索引)選擇大量可用的包,這是一個軟體倉庫。
  • 如何編寫和運行Python程序
    第一種方式是進入Pyhton的安裝目錄,直接運行python.exe程序;第二種方式是進入Windows命令行窗口,在命令行窗口啟動python.exe。在Windows命令行窗口啟動Python交互式解釋器,首先需要將Python安裝目錄的路徑,添加到Path系統環境變量。否則,只能進入Python安裝目錄啟動交互式解釋器。
  • 5種帶你輕鬆分析Python代碼的軟體庫
    對於Python而言,大家往往受益的是它能夠快速地編寫代碼,而忽略了它是否能夠快速地運行,並及時完成既定的任務。因此,在出現程序運行緩慢時,我們有必要從代碼層面上,找出拖慢的位置和原因,並對其進行處理。
  • 漫畫:如何分析運行中的 Python 程序?
    要排查的是線上正在運行的 Python 程序2.「凌晨 3 點多的時候可能出現」,表示問題並不是每天都出現的線上服運行在真實環境,使用真實數據長時間運行,這種非必發性的錯誤通常難以在測試服或灰度服中發現,而且這種錯誤看日誌通常難以判斷出現這種問題的真正原因,可能其他地方的代碼出現了問題,但沒有被處理,導致異常狀態一直堆積,一段時間後才出現的問題。