亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

Python最佳代碼實(shí)踐:性能、內(nèi)存和可用性!

遵循最佳做法的代碼庫在當(dāng)今世界能得到高度評(píng)價(jià)。如果您的項(xiàng)目是開源的,這會(huì)是一個(gè)吸引優(yōu)秀開發(fā)人員的方式。作為開發(fā)人員,您想要編寫高效且優(yōu)化的代碼:

占用盡可能小的內(nèi)存、執(zhí)行地更快、看起來整潔、文檔正確、遵循標(biāo)準(zhǔn)風(fēng)格指南,并且易于被新開發(fā)者理解。

這里討論的實(shí)踐可能有助于您為開源組織做出貢獻(xiàn),向在線評(píng)審(Online Judge)提交解決方案,使用機(jī)器學(xué)習(xí)處理大量數(shù)據(jù)處理問題,或開發(fā)自己的項(xiàng)目。

Python最佳代碼實(shí)踐:性能、內(nèi)存和可用性!

實(shí)踐 1:盡量不要對(duì)內(nèi)存置之不理

Python 內(nèi)存管理器內(nèi)部確保對(duì)這個(gè)專用堆的管理。當(dāng)您創(chuàng)建對(duì)象時(shí),Python 虛擬機(jī)處理所需的內(nèi)存,并決定將其放置在內(nèi)存布局中的特定位置。與 C/C ++ 不同,Python 解釋器會(huì)進(jìn)行內(nèi)存管理,用戶無法自己控制。Python 中的內(nèi)存管理涉及包含所有Python對(duì)象和數(shù)據(jù)結(jié)構(gòu)的專用堆。一個(gè)簡(jiǎn)單的 Python 程序在內(nèi)存上可能不會(huì)引起很多問題,但在高內(nèi)存消耗的項(xiàng)目中內(nèi)存使用變得至關(guān)重要。從一開始開發(fā)大項(xiàng)目時(shí),合理使用內(nèi)存是明智的。

然而,如何更好地了解事情的工作原理和不同的方法來做事情,可以幫助您最大限度地減少程序的內(nèi)存使用量。

?使用生成器來計(jì)算大量的結(jié)果

生成器可進(jìn)行惰性計(jì)算。您可以通過遍歷來使用它們:顯示地使用 “for” 或者隱式地將其傳遞給任何方法或構(gòu)造。

生成器可以返回多個(gè)項(xiàng),就像返回一個(gè)列表 —— 不是一次返回所有,而是一個(gè)接一個(gè)地返回。生成器會(huì)暫停,直到下一個(gè)項(xiàng)被請(qǐng)求。在?這里[1]?閱讀更多關(guān)于 Python 生成器的內(nèi)容。

?對(duì)于大量數(shù)字/數(shù)據(jù)的處理,您可以使用像 Numpy 這樣的庫,它可以優(yōu)雅地處理內(nèi)存管理。?使用 format 而不是 “+” 來生成字符串 —— 在Python中,str 是不可變的,所以每對(duì)連接都必須將左、右字符串復(fù)制到新的字符串中。如果連接長度為10的四個(gè)字符串,則將復(fù)制(10+10) + ((10+10)+10) + (((10+10)+10)+10) = 90 個(gè)字符,而不是 40 字符。隨著字符串?dāng)?shù)量和大小的增加,事情會(huì)變得越來越糟。Java 有時(shí)將一系列的連接轉(zhuǎn)換為使用StringBuilder 來優(yōu)化這種情況,但是 CPython 沒有。因此,建議使用 .format 或 % 語法。如果您不能在 .format 和 % 之間選擇,請(qǐng)查看?這個(gè)有趣的 StackOverflow 問題[2]?。?定義 Python 類時(shí)使用槽(slots)。您可以通過將類中的?slots?設(shè)置為固定的屬性名稱列表,來告訴 Python 不要使用動(dòng)態(tài)字典,只為一組固定的屬性分配空間,從而消除了為每個(gè)對(duì)象使用一個(gè)字典的開銷。在?這里[3]?閱讀更多關(guān)于槽的內(nèi)容。?您可以通過使用內(nèi)置的模塊(如 resource 和 objgraph)來跟蹤對(duì)象級(jí)別的內(nèi)存使用情況。?在 Python 中管理內(nèi)存泄漏可能是一項(xiàng)艱巨的任務(wù),但幸運(yùn)的是有一些工具(如 heapy)用于調(diào)試內(nèi)存泄漏。Heapy 可以與 objgraph 一起使用來觀察 diff 對(duì)象的分配隨時(shí)間而增長。Heapy 可以顯示哪些對(duì)象占用最多的內(nèi)存。Objgraph 可以幫助您找到反向引用,以明白為什么它們不能被釋放。您可以在?這里[4]?閱讀更多關(guān)于在Python中診斷內(nèi)存泄漏的信息。

您可以在?這里[5]?閱讀由 Theano 的開發(fā)人員編寫的關(guān)于 Python 內(nèi)存管理的細(xì)節(jié)。

實(shí)踐2:Python2 還是 Python3

當(dāng)開始一個(gè)新的 Python 項(xiàng)目,或是只學(xué)習(xí) Python,您可能會(huì)發(fā)現(xiàn)自己在選擇 Python2 還是Python3 上十分糾結(jié)。這是一個(gè)廣泛討論的話題,在網(wǎng)上有許多觀點(diǎn)和好的解釋。

一方面,Python3 有一些很棒的新特性。另一方面,您可能希望使用僅支持 Python2 的包,而Python3 不能向后兼容。這意味著在 Python3.x 的解釋器上運(yùn)行 Python2 的代碼可能會(huì)拋出錯(cuò)誤。

不過,編寫能同時(shí)跑在 Python2 和 Python3 解釋器的代碼是可能的。最常見的方法是使用_future、builtins 和 six 這樣的軟件包來維護(hù)一個(gè)簡(jiǎn)單、干凈的 Python3.x 兼容代碼庫,能以最小的開銷同時(shí)支持Python2 和 Python3。

python-future 是 Python2 和 Python3 之間的缺失兼容層。它提供 future 和 past 的包,能夠向前或向后移植 Python2 和 Python3 的特性。它還帶有 futurize 和 pasteurize,定制化的 2 到 3 基礎(chǔ)的腳本,可以幫助您輕松地將 Py2 或 Py3 代碼逐模塊轉(zhuǎn)換為干凈的支持 Python2 和 Python3 的Py3 風(fēng)格的代碼庫。

請(qǐng)查看 Ed Schofield 編寫的超贊的 Python 2-3 兼容代碼?手抄冊(cè)[6](需翻墻)。如果相比閱讀,您更喜歡視頻,可以在 PyCon AU 2014 上找到他的演講,“編寫 2/3 兼容的代碼[7]”(需翻墻)。

實(shí)踐3:寫出美麗的代碼

分享代碼是一個(gè)有益的嘗試。無論什么動(dòng)機(jī),如果人們發(fā)現(xiàn)您的代碼難以使用或理解,那么您的良好意圖可能沒有達(dá)到預(yù)期。幾乎每個(gè)組織都遵循開發(fā)人員必須遵循的風(fēng)格指南,以保持一致性、易于調(diào)試和協(xié)作。Python 的禪就像一個(gè)迷你風(fēng)格的 Python 設(shè)計(jì)指南。主流的 Python 風(fēng)格指南包括:

1.PEP-8 風(fēng)格指南2.Python 習(xí)語和效率3.Google Python 風(fēng)格指南

這些準(zhǔn)則討論了如何使用:空格、逗號(hào)和大括號(hào),對(duì)象命名指南等。盡管它們?cè)谀承┣闆r下可能發(fā)生沖突,但它們都具有相同的目標(biāo) —— “清晰、可讀和可調(diào)試的代碼標(biāo)準(zhǔn)”。

堅(jiān)持一個(gè)指南,或遵循自己的,但不要試圖跟隨與廣泛接受的標(biāo)準(zhǔn)大不相同的內(nèi)容。

使用靜態(tài)代碼分析工具

有許多可用的開源工具能夠使您的代碼符合標(biāo)準(zhǔn)的風(fēng)格指南和編寫代碼的最佳實(shí)踐。

Pylint 是一個(gè) Python 工具,用于檢查模塊的編碼標(biāo)準(zhǔn)。Pylint 可以快速輕松地查看您的代碼是否捕捉到了 PEP-8 的精髓,因此對(duì)其他潛在用戶是“友好的”。

它還為您提供優(yōu)良的指標(biāo)和統(tǒng)計(jì)報(bào)告,可幫助您判斷代碼質(zhì)量。您還可以通過創(chuàng)建自己的 .pylintrc 文件進(jìn)行自定義和使用。

Pylint 不是唯一的選擇 —— 還有其他工具,如 PyChecker,PyFlakes 以及像 pep8 和 flakes8 這樣的包。

我的建議是使用 coala,一個(gè)統(tǒng)一的靜態(tài)代碼分析框架,旨在通過單個(gè)框架提供語言非特定的代碼分析。Coala 支持我之前提到的所有的linting工具,并且是高度可定制的。

正確地文檔說明代碼

這方面對(duì)您的代碼庫的可用性和可讀性至關(guān)重要。始終建議您盡可能廣泛地文檔說明您的代碼,以便其他開發(fā)人員更容易了解您的代碼。

功能的典型內(nèi)聯(lián)文檔應(yīng)包括:

?該功能的一行概要。?如果適用的話,提供交互示例。這些可以讓新開發(fā)人員參考,以快速了解功能的使用和預(yù)期的輸出。您也可以使用 doctest 模塊來確保這些示例的正確性(以測(cè)試方式運(yùn)行)。請(qǐng)參閱 doctest 文檔 中的示例。?參數(shù)文檔(通常一行描述參數(shù)及其在函數(shù)中的作用)?返回類型的文檔(除非您的函數(shù)沒有返回任何內(nèi)容!)

Sphinx 是廣泛使用的用于生成和管理項(xiàng)目文檔的工具。它提供了大量方便的功能,可以減少您編寫標(biāo)準(zhǔn)文檔的工作量。此外,您可以將文檔推送到 Read the Docs,這是最常用的托管項(xiàng)目文檔的方式。

Hitchiker's guide to Python for documentation[8]?(筆者翻譯成了中文版——Python 最佳實(shí)踐指南[9])包含一些有趣的信息,在文檔說明代碼時(shí)可能對(duì)您有用。

實(shí)踐4:提高性能

多進(jìn)程,而不是多線程

改進(jìn)多任務(wù)代碼的執(zhí)行時(shí)間時(shí),您可能希望利用 CPU 中的多核同時(shí)執(zhí)行多個(gè)任務(wù)。產(chǎn)生幾個(gè)線程并讓它們并發(fā)執(zhí)行可能看起來很直觀,但是由于 Python 中的全局解釋器鎖,所有的線程都是在相同的核上輪流運(yùn)行。

為了實(shí)現(xiàn) Python 的實(shí)際并行化,您可能需要使用 Python 的 multiprocessing 模塊。另一個(gè)解決方案可以是將任務(wù)外包給:

1.操作系統(tǒng)(通過多進(jìn)程)2.一些調(diào)用您的 Python 代碼的外部應(yīng)用程序(例如 Spark 或 Hadoop)3.您的Python代碼所調(diào)用的代碼(例如,您可以讓 Python 代碼調(diào)用C函數(shù),來執(zhí)行昂貴的多線程內(nèi)容)。

除了并行,還有其他方法可以提高您的性能。其中一些包括:

?使用最新版本的 Python:這是最直接的方法,因?yàn)樾碌母峦ǔ0▽?duì)已經(jīng)存在功能性能方面的增強(qiáng)。?盡可能使用內(nèi)置函數(shù):這也符合 DRY 原則 —— 內(nèi)置函數(shù)由世界上一些最好的 Python 開發(fā)人員仔細(xì)設(shè)計(jì)和審查,所以它們通常是最好的方式。?考慮使用 Ctypes:Ctypes 提供了一個(gè)在 Python 代碼中調(diào)用 C 共享函數(shù)的接口。C 是一種更接近機(jī)器級(jí)別的語言,與 Python 中的類似實(shí)現(xiàn)相比,代碼執(zhí)行速度更快。?使用 Cython:Cython 是一種 Python 語言的超集,允許用戶調(diào)用 C 函數(shù)并具有靜態(tài)類型聲明,最后生成一份更簡(jiǎn)單的最終代碼,可能會(huì)執(zhí)行得快得多。?使用 PyPy:PyPy 是具有 JIT(即時(shí))編譯器的另一個(gè) Python 實(shí)現(xiàn),可以使您的代碼執(zhí)行更快。雖然我從未嘗試過 PyPy,但它也聲稱會(huì)減少程序的內(nèi)存消耗。像 Quora 這樣的公司實(shí)際上在生產(chǎn)環(huán)境中使用 PyPy。?設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu):適用于各種語言。確保您正在為目標(biāo)使用正確的數(shù)據(jù)結(jié)構(gòu),在正確的地方聲明變量,明智地利用標(biāo)識(shí)符范圍,并在任何有意義的地方緩存結(jié)果等。

我可以給出的一個(gè)具體的例子是:Python 通常在訪問全局變量和解析函數(shù)地址時(shí)很慢,所以將它們分配到當(dāng)前作用域內(nèi)的一個(gè)局部變量,然后訪問它們,速度會(huì)更快。

實(shí)踐5:分析您的代碼

通常,分析您的代碼的覆蓋度、質(zhì)量和性能是有幫助的。Python 附帶了 cProfile 模塊來幫助評(píng)估性能。它不僅給出了總運(yùn)行時(shí)間,還分別對(duì)每個(gè)函數(shù)進(jìn)行了計(jì)時(shí)。

然后,它會(huì)告訴您每個(gè)函數(shù)調(diào)用的時(shí)間,這樣可以很容易地確定要優(yōu)化的地方。以下是cProfile 的一個(gè)示例分析:

Python最佳代碼實(shí)踐:性能、內(nèi)存和可用性!

?memory_profiler 是一個(gè)用于監(jiān)視進(jìn)程內(nèi)存消耗的Python模塊,它能對(duì) Python 程序的內(nèi)存消耗進(jìn)行逐行分析。?objgraph 能顯示前N個(gè)占用 Python 程序內(nèi)存的對(duì)象、在一段時(shí)間內(nèi)刪除或添加的對(duì)象以及腳本中給定對(duì)象的所有引用。?resource 為程序測(cè)量和控制系統(tǒng)資源使用提供了基本機(jī)制。該模塊的兩個(gè)主要用途包括限制資源分配和獲取有關(guān)資源當(dāng)前使用情況的信息。

實(shí)踐6:測(cè)試和持續(xù)集成

測(cè)試

寫單元測(cè)試是個(gè)好習(xí)慣。如果您認(rèn)為寫測(cè)試不值得您努力,請(qǐng)查看此 StackOverflow 問題[10]。最好在編碼之前或期間編寫測(cè)試。Python 提供了unittest 模塊來為函數(shù)和類編寫單元測(cè)試。此外還有如下框架:

?nose —— 可以運(yùn)行 unittest 測(cè)試,并具有較少的樣板。?pytest —— 也運(yùn)行unittest測(cè)試,更少的樣板,更好的報(bào)告和很多很酷,額外的功能。

為了得到良好的比較,請(qǐng)閱讀這里[11]的介紹。

不要忘記 doctest 模塊,它使用內(nèi)聯(lián)文檔中的交互式示例來測(cè)試源代碼。

測(cè)量覆蓋度

Coverage 是測(cè)量 Python 程序代碼覆蓋度的工具。它監(jiān)控您的程序,關(guān)注代碼的哪些部分已被執(zhí)行,然后分析源碼以識(shí)別可能已被執(zhí)行但沒有執(zhí)行的代碼。

覆蓋度測(cè)量通常用于測(cè)量測(cè)試的有效性。它可以顯示您的代碼的哪些部分被測(cè)試執(zhí)行了,哪些沒有。通常建議有 100% 的分支覆蓋度,這意味著您的測(cè)試應(yīng)該能夠執(zhí)行和驗(yàn)證項(xiàng)目的每個(gè)分支的輸出。

持續(xù)集成

從一開始就為您的項(xiàng)目配置 CI 系統(tǒng),對(duì)于您的項(xiàng)目來說可以非常有用。您可以使用 CI 服務(wù)輕松測(cè)試代碼庫的各個(gè)方面。CI 中的一些典型檢查包括:

?在現(xiàn)實(shí)環(huán)境中運(yùn)行測(cè)試。有些情況下,測(cè)試在某些架構(gòu)上通過,而在其他架構(gòu)上失敗。CI 服務(wù)可以讓您在不同的系統(tǒng)架構(gòu)上運(yùn)行測(cè)試。?對(duì)您的代碼庫執(zhí)行覆蓋度約束。?構(gòu)建和部署您的代碼到生產(chǎn)環(huán)境(您可以在不同的平臺(tái)上這樣做)

現(xiàn)今有一些 CI 服務(wù):一些最受歡迎的有Travis、Circle(適用于OSX和Linux)和Appveyor(適用于Windows)。根據(jù)我最初的使用,像 Semaphore CI 這樣的新興產(chǎn)品看起來是可靠的。Gitlab(另一個(gè)Git存儲(chǔ)庫管理平臺(tái),如 Github)也支持 CI,不過如同其他服務(wù)一樣,您需要明確配置它。

References

[1]??https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/
[2]?https://stackoverflow.com/questions/5082452/string-formatting-vs-format
[3]?https://stackoverflow.com/questions/472000/usage-of-slots
[4]??https://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html
[5]?http://deeplearning.net/software/theano/tutorial/python-memory-management.html
[6]?http://python-future.org/compatible_idioms.html
[7]?https://www.youtube.com/watch?v=KOqk8j11aAI&t=10m14s
[8]?https://docs.python-guide.org/writing/documentation/
[9]?https://pythonguidecn.readthedocs.io/zh/latest/
[10]?https://stackoverflow.com/questions/67299/is-unit-testing-worth-the-effort
[11]?https://pythontesting.net/start-here/

?作者:Satwik Kansal,譯者:Prodesire
文章轉(zhuǎn)載:菜鳥學(xué)Python
?譯文:https://zhuanlan.zhihu.com/p/28675694

(版權(quán)歸原作者所有,侵刪)

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國內(nèi)好評(píng)如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!