欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

提高python代碼運行效率的一些建議

 更新時間:2020年09月29日 09:50:22   作者:淺笑·  
這篇文章主要介紹了提高python代碼運行效率的一些建議,幫助大家優(yōu)化python代碼,提高運行效率,感興趣的朋友可以了解下

1. 優(yōu)化代碼和算法

一定要先好好看看你的代碼和算法。許多速度問題可以通過實現(xiàn)更好的算法或添加緩存來解決。本文所述都是關(guān)于這一主題的,但要遵循的一些一般指導(dǎo)方針是:

  • 測量,不要猜測。 測量代碼中哪些部分運行時間最長,先把重點放在那些部分上。
  • 實現(xiàn)緩存。 如果你從磁盤、網(wǎng)絡(luò)和數(shù)據(jù)庫執(zhí)行多次重復(fù)的查找,這可能是一個很大的優(yōu)化之處。
  • 重用對象,而不是在每次迭代中創(chuàng)建一個新對象。Python 必須清理你創(chuàng)建的每個對象才能釋放內(nèi)存,這就是所謂的“垃圾回收”。許多未使用對象的垃圾回收會大大降低軟件速度。
  • 盡可能減少代碼中的迭代次數(shù),特別是減少迭代中的操作次數(shù)。
  • 避免(深度)遞歸。 對于 Python 解釋器來說,它需要大量的內(nèi)存和維護(hù)(Housekeeping)。改用生成器和迭代之類的工具。
  • 減少內(nèi)存使用。 一般來說,盡量減少內(nèi)存的使用。例如,對一個巨大的文件進(jìn)行逐行解析,而不是先將其加載到內(nèi)存中。
  • 不要這樣做。 聽起來很傻是吧?但是你真的需要執(zhí)行這個操作嗎?不能晚點兒再執(zhí)行嗎?或者可以只執(zhí)行一次,并且它的結(jié)果可以存儲起來,而不是一遍又一遍地反復(fù)計算?

2. 使用 PyPy

你可能正在使用 Python 的參考實現(xiàn) CPython。之所以稱為 CPython,是因為它是用 C 語言編寫的。如果你確定你的代碼是 CPU 密集型(CPU bound)(如果你不知道這一術(shù)語,請參見本文“使用線程”一節(jié))的話,那么你應(yīng)該研究一下 PyPy,它是 CPython 的替代方案。這可能是一種快速解決方案,無需更改任何一行代碼。

PyPy 聲稱,它的平均速度比 CPython 要快 4.4 倍。它是通過使用一種稱為 Just-in-time(JIT,即時編譯)技術(shù)來實現(xiàn)的。Java 和 .NET 框架就是 JIT 編譯的其他著名的例子。相比之下,CPython 使用解釋來執(zhí)行代碼。雖然這一做法提供了很大的靈活性,但速度也變得慢了下來。

使用 JIT,你的代碼是在運行程序時即時編譯的。它結(jié)合了 Ahead-of-time(AOT,提前編譯)技術(shù)的速度優(yōu)勢(由 C 和 C++ 等語言使用)和解釋的靈活性。另一個優(yōu)點是 JIT 編譯器可以在運行時不斷優(yōu)化代碼。代碼運行的時間越長,它就會變得越優(yōu)化。

PyPy 在過去幾年中取得了長足的進(jìn)步,通常情況下,它可以作為 Python 2 和 Python 3 的簡易替換方案。使用 Pipenv 這樣的工具,它也可以完美地工作,試試看吧!

3. 使用線程

大部分軟件都是 IO 密集型,而不是 CPU 密集型。如果你對這些術(shù)語還不熟悉的話,請看看下面的解釋:

  • IO 密集型(I/O bound):軟件主要是等待輸入 / 輸出操作完成才能工作。在從網(wǎng)絡(luò)或緩慢的存儲中獲取數(shù)據(jù)時,通常會出現(xiàn)這種情況。
  • CPU 密集型(CPU bound):軟件占用了大量的 CPU 資源。它使用了 CPU 所有的能力來產(chǎn)生所需的結(jié)果。

在等待來自網(wǎng)絡(luò)或磁盤的應(yīng)答時,你可以使用多個線程使其他部分保持運行狀態(tài)。

一個線程是一個獨立的執(zhí)行序列。默認(rèn)情況下,Python 程序有一個主線程。但你可以創(chuàng)建更多的主線程,并讓 Python 在它們之間切換。這種切換發(fā)生得如此之快,以至于它們看上去就好像是在同時并排運行一樣。

但與其他編程語言不同的是,Python 并不是同時運行的,而是輪流運行。這是因為 Python 中有一種全局解釋器鎖( Global Interpreter Lock,GIL)機制。這一點,以及 threading 庫在 我撰寫的關(guān)于 Python 并發(fā)性的文章 有詳細(xì)的解釋。

我們得到的結(jié)論是,線程對于 IO 密集型的軟件有很大的影響,但對 CPU 密集型的軟件毫無用處。

這是為什么呢?很簡單。當(dāng)一個線程在等待來自網(wǎng)絡(luò)的答復(fù)時,其他線程可以繼續(xù)運行。如果你要執(zhí)行大量的網(wǎng)絡(luò)請求,線程可以帶來巨大的差異。如果你的線程正在進(jìn)行繁重的計算,那么它們只是等待輪到它們繼續(xù)計算,線程化只會帶來更多的開銷。

4. 使用 Asyncio

Asyncio 是 Python 中一個相對較新的核心庫。它解決了與線程相同的問題:它加快了 IO 密集型軟件的速度,但這是以不同的方式實現(xiàn)的。我將立即坦承我并非 Python 的 asyncio 擁躉。它相當(dāng)復(fù)雜,特別是對于初學(xué)者來說。我遇到的另一個問題是, asyncio 庫在過去幾年中有了很大的發(fā)展。網(wǎng)上的教程和示例代碼常常已經(jīng)過時。不過,這并不意味著它就毫無用處。

5 同時使用多個處理器

如果你的軟件是 CPU 密集型的,你通??梢杂靡环N可以同時使用更多處理器的方式重寫你的代碼。通過這種方式,你就可以線性地調(diào)整執(zhí)行速度。

這就是所謂的并行性,但并不是所有的算法都可以并行運行。例如,簡單的將遞歸算法進(jìn)行并行化是不可能的。但是幾乎總有一種替代算法可以很好地并行工作。

使用更多處理處理器有兩種方式:

  1. 在同一臺機器內(nèi)使用多個處理器和 / 或內(nèi)核。在 Python 中,這可以通過 multiprocessing 庫來完成。
  2. 使用計算機網(wǎng)絡(luò)來使用多個處理器,分布在多臺計算機上。我們稱之為分布式計算。

這篇 關(guān)于 Python 并發(fā)性的文章 側(cè)重于介紹如何在一臺機器的范圍內(nèi)擴展 Python 軟件的方法。它還介紹了 multiprocessing 庫。如果你認(rèn)為這是你需要的資料,一定要去看看。

與 threading 庫不同, multiprocessing 庫繞過了 Python 的全局解釋器鎖。它實際上是通過派生多個 Python 實例來實現(xiàn)這一點的。因此,現(xiàn)在你可以讓多個 Python 進(jìn)程同時運行你的代碼,而不是在單個 Python 進(jìn)程中輪流運行線程。

multiprocessing 庫和 threading 庫非常相似??赡艹霈F(xiàn)的問題是:為什么還要考慮線程呢?答案是可以猜得到的。線程是“輕量”的:它需要更少的內(nèi)存,因為它只需要一個正在運行的 Python 解釋器。產(chǎn)生新進(jìn)程也還有其開銷。因此,如果你的代碼是 IO 密集型的,線程可能就足夠好了。

一旦你實現(xiàn)了軟件的并行工作,那么在使用 Hadoop 之類的分布式計算方面就前進(jìn)了一小步。通過利用云計算平臺,你可以相對輕松地進(jìn)行擴展規(guī)模。例如,你可以在云端中處理大型數(shù)據(jù)集,并在本地使用結(jié)果。使用混合操作的方式,你可以節(jié)省一些資金,因為云端中的算力非常昂貴。

總結(jié)

總結(jié)起來就是:

  • 首先考慮優(yōu)化你的算法和代碼。
  • 如果原始速度可以解決你的問題,請考慮使用 PyPy。
  • 對 IO 密集型軟件使用 threading 庫和 asyncio 。
  • 使用 multiprocessing 庫解決 CPU 密集型問題。
  • 如果所有這些措施還不夠的話,可以利用 Hadoop 等云計算平臺進(jìn)行擴展規(guī)模。

以上就是提高python代碼運行效率的一些建議的詳細(xì)內(nèi)容,更多關(guān)于提高python代碼運行效率的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論