8個(gè)核心編碼技巧输硝,可實(shí)現(xiàn)更快的python運(yùn)行速度 小鄂爾多斯

前言

總的來(lái)說(shuō),人們使用python是因?yàn)樗奖闱乙子诰幊痰炒埽皇且驗(yàn)樗芸燹忠4罅康牡谌綆?kù)和對(duì)Python的工業(yè)支持的廣泛性彌補(bǔ)了它沒(méi)有Java或C的原始性能。開(kāi)發(fā)速度優(yōu)先于執(zhí)行速度幌衣。

但在許多情況下矾削,它不必是一個(gè)非此即彼的命題。適當(dāng)?shù)貎?yōu)化豁护,Python應(yīng)用程序可以以驚人的速度運(yùn)行——也許不是Java或C快僵控,但對(duì)于Web應(yīng)用程序萝勤、數(shù)據(jù)分析沸呐、管理和自動(dòng)化工具以及其他大多數(shù)目的來(lái)說(shuō)都足夠快优训。實(shí)際上,您可能會(huì)忘記您是在用應(yīng)用程序性能來(lái)?yè)Q取開(kāi)發(fā)人員的生產(chǎn)力班缎。

優(yōu)化python性能并不能歸結(jié)為任何一個(gè)因素蝴光。相反,它是關(guān)于應(yīng)用所有可用的最佳實(shí)踐吝梅,并選擇最適合當(dāng)前場(chǎng)景的最佳實(shí)踐虱疏。(Dropbox中的人們有一個(gè)關(guān)于Python優(yōu)化功能最引人注目的例子惹骂。)

在這篇文章中苏携,我將概述許多常見(jiàn)的Python優(yōu)化。其中一些是只需將一個(gè)項(xiàng)目切換到另一個(gè)項(xiàng)目(如更改python解釋器)即可實(shí)現(xiàn)的嵌入式度量对粪,但實(shí)現(xiàn)最大回報(bào)的項(xiàng)目將需要更詳細(xì)的工作右冻。

1装蓬。Memoize(緩存)重復(fù)使用的數(shù)據(jù)

當(dāng)你能做到一次并保存結(jié)果時(shí),千萬(wàn)不要做一千次工作纱扭。如果有一個(gè)經(jīng)常調(diào)用的函數(shù)返回可預(yù)測(cè)的結(jié)果牍帚,那么python為您提供了將結(jié)果緩存到內(nèi)存中的選項(xiàng)。返回相同結(jié)果的后續(xù)調(diào)用幾乎會(huì)立即返回乳蛾。

各種各樣的例子展示了如何做到這一點(diǎn)暗赶;我最喜歡的記憶幾乎是最少的。python的一個(gè)本機(jī)庫(kù)functools具有@functools.lru緩存裝飾器肃叶,它緩存最近對(duì)函數(shù)的n個(gè)調(diào)用蹂随。當(dāng)正在緩存的值發(fā)生變化,但在特定的時(shí)間窗口內(nèi)是相對(duì)靜態(tài)的時(shí)因惭,這很方便岳锁。一天中最新使用的項(xiàng)目列表就是一個(gè)很好的例子。

2蹦魔。將數(shù)學(xué)移動(dòng)到numpy

如果您正在進(jìn)行基于矩陣或數(shù)組的數(shù)學(xué)運(yùn)算激率,并且不希望Python解釋器妨礙您的工作,請(qǐng)使用numpy勿决。通過(guò)利用C庫(kù)進(jìn)行繁重的工作乒躺,numpy提供了比本機(jī)python更快的數(shù)組處理。它還比Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)更有效地存儲(chǔ)數(shù)字?jǐn)?shù)據(jù)剥险。

相對(duì)來(lái)說(shuō)聪蘸,非異類(lèi)的數(shù)學(xué)也可以被numpy大大加快。該包為許多常見(jiàn)的python數(shù)學(xué)操作(如min和max)提供了替換表制,這些操作的速度比原來(lái)的python快很多倍健爬。

numpy的另一個(gè)好處是更有效地使用大型對(duì)象的內(nèi)存,比如擁有數(shù)百萬(wàn)個(gè)項(xiàng)目的列表么介。一般來(lái)說(shuō)娜遵,像numpy中那樣的大型對(duì)象如果用傳統(tǒng)的python來(lái)表示,則占用大約四分之一的內(nèi)存壤短。請(qǐng)注意设拟,它有助于從作業(yè)的正確數(shù)據(jù)結(jié)構(gòu)開(kāi)始,即優(yōu)化本身久脯。

重寫(xiě)python算法以使用numpy需要一些工作纳胧,因?yàn)閿?shù)組對(duì)象需要使用numpy的語(yǔ)法聲明。但是numpy在實(shí)際的數(shù)學(xué)運(yùn)算中使用了python現(xiàn)有的習(xí)語(yǔ)(+帘撰、-跑慕,等等),所以從長(zhǎng)遠(yuǎn)來(lái)看,切換到numpy并不會(huì)太令人迷惑核行。

3牢硅。使用C庫(kù)

numpy使用C語(yǔ)言編寫(xiě)的庫(kù)是一種很好的模擬策略。如果有一個(gè)現(xiàn)有的C庫(kù)可以滿足您的需要芝雪,那么Python及其生態(tài)系統(tǒng)提供了幾個(gè)選項(xiàng)來(lái)連接到該庫(kù)并利用其速度减余。

最常見(jiàn)的方法是使用Python的CTypes庫(kù)。因?yàn)閏types與其他python應(yīng)用程序(和運(yùn)行時(shí))廣泛兼容惩系,所以它是最佳的開(kāi)始位置位岔,但它遠(yuǎn)不是鎮(zhèn)上唯一的游戲。cffi項(xiàng)目為c.cython提供了一個(gè)更優(yōu)雅的接口(見(jiàn)下文)堡牡,也可以用來(lái)包裝外部庫(kù)赃承,盡管代價(jià)是必須學(xué)習(xí)cython的標(biāo)記。

學(xué)習(xí)從來(lái)不是一個(gè)人的事情悴侵,要有個(gè)相互監(jiān)督的伙伴瞧剖,工作需要學(xué)習(xí)python或者有興趣學(xué)習(xí)python的伙伴可以私信回復(fù)小編“學(xué)習(xí)” 獲取資料,一起學(xué)習(xí)

4可免。與多處理并行

傳統(tǒng)的python應(yīng)用程序——那些在cpython中實(shí)現(xiàn)的應(yīng)用程序——一次只執(zhí)行一個(gè)線程抓于,以避免在使用多個(gè)線程時(shí)出現(xiàn)狀態(tài)問(wèn)題。這是臭名昭著的全球口譯員鎖(gil)浇借。它的存在有充分的理由捉撮,這并沒(méi)有使它變得更加華麗。

隨著時(shí)間的推移妇垢,gil的效率顯著提高(運(yùn)行python 3而不是python 2的另一個(gè)原因)巾遭,但核心問(wèn)題仍然存在。一個(gè)cpython應(yīng)用程序可以是多線程的闯估,但是cpython不允許這些線程在多個(gè)核心上并行運(yùn)行灼舍。

為了解決這個(gè)問(wèn)題,python提供了多處理模塊來(lái)在不同的核心上運(yùn)行python解釋器的多個(gè)實(shí)例涨薪。狀態(tài)可以通過(guò)共享內(nèi)存或服務(wù)器進(jìn)程來(lái)共享骑素,數(shù)據(jù)可以通過(guò)隊(duì)列或管道在進(jìn)程實(shí)例之間傳遞。

您仍然需要在進(jìn)程之間手動(dòng)管理狀態(tài)刚夺。另外献丑,在啟動(dòng)多個(gè)Python實(shí)例并在其中傳遞對(duì)象的過(guò)程中,不會(huì)有太多的開(kāi)銷(xiāo)侠姑。但是對(duì)于長(zhǎng)期運(yùn)行的進(jìn)程來(lái)說(shuō)创橄,多處理庫(kù)是非常有用的,因?yàn)樗梢詮目绾诵牡牟⑿行灾蝎@益莽红。

另外妥畏,使用C庫(kù)的python模塊和包(如numpy)完全避免使用gil。這也是他們被推薦提速的另一個(gè)原因。

5咖熟。知道你的庫(kù)在做什么

簡(jiǎn)單地輸入XYZ并利用無(wú)數(shù)其他程序員的工作是多么方便!但是您需要知道柳畔,第三方庫(kù)可以改變應(yīng)用程序的性能馍管,而不是總是為了更好。

有時(shí)薪韩,這以明顯的方式表現(xiàn)出來(lái)确沸,例如當(dāng)來(lái)自特定庫(kù)的模塊構(gòu)成瓶頸時(shí)。(再次強(qiáng)調(diào)俘陷,剖析會(huì)有所幫助罗捎。)有時(shí)情況不那么明顯。示例:Pyglet是一個(gè)用于創(chuàng)建窗口化圖形應(yīng)用程序的簡(jiǎn)便庫(kù)拉盾,它自動(dòng)啟用調(diào)試模式桨菜,這會(huì)顯著影響性能,直到顯式禁用它為止捉偏。除非您閱讀文檔倒得,否則您可能永遠(yuǎn)不會(huì)意識(shí)到這一點(diǎn)。閱讀并被告知夭禽。

6霞掺。注意平臺(tái)

python運(yùn)行跨平臺(tái),但這并不意味著每個(gè)操作系統(tǒng)(windows讹躯、linux菩彬、os x)的特性都是在python下抽象出來(lái)的。大多數(shù)時(shí)候潮梯,這意味著要了解平臺(tái)的具體情況骗灶,比如路徑命名約定,對(duì)于這些約定秉馏,有助手函數(shù)矿卑。

但在性能方面,了解平臺(tái)差異也很重要沃饶。例如母廷,在Windows上,需要計(jì)時(shí)器精度小于15毫秒(例如糊肤,對(duì)于多媒體)的python腳本將需要使用Windows API調(diào)用來(lái)訪問(wèn)高分辨率計(jì)時(shí)器或提高計(jì)時(shí)器分辨率琴昆。

7。與PyPy同行

cpython是Python最常用的實(shí)現(xiàn)馆揉,它將兼容性優(yōu)先于原始速度业舍。對(duì)于那些想把速度放在首位的程序員來(lái)說(shuō),有pypy,一個(gè)配備了jit編譯器的python實(shí)現(xiàn)來(lái)加速代碼執(zhí)行舷暮。

因?yàn)閜ypy是作為cpython的替代品而設(shè)計(jì)的态罪,所以它是快速提高性能的最簡(jiǎn)單方法之一。許多常見(jiàn)的python應(yīng)用程序?qū)⒃趐ypy上運(yùn)行下面。一般來(lái)說(shuō)复颈,應(yīng)用程序越依賴于“普通”的python,就越有可能在pypy上運(yùn)行而不進(jìn)行修改沥割。

然而耗啦,充分利用PYPY可能需要測(cè)試和研究。您會(huì)發(fā)現(xiàn)長(zhǎng)時(shí)間運(yùn)行的應(yīng)用程序從Pypy獲得最大的性能收益机杜,因?yàn)榫幾g器會(huì)分析一段時(shí)間后的執(zhí)行情況帜讲。對(duì)于運(yùn)行和退出的短腳本,您最好使用cpython椒拗,因?yàn)樾阅芴嵘蛔阋钥朔﨡IT的開(kāi)銷(xiāo)似将。

請(qǐng)注意,pypy對(duì)python 3的支持仍然落后于幾個(gè)版本蚀苛;它目前支持python 3.2.5玩郊。使用最新的python特性(如async和await-co例程)的代碼將無(wú)法工作。最后枉阵,使用ctypes的python應(yīng)用程序的行為可能并不總是如預(yù)期的那樣译红。如果您正在編寫(xiě)可能同時(shí)在pypy和cpython上運(yùn)行的東西,那么為每個(gè)解釋器分別處理用例可能是有意義的兴溜。

其他通過(guò)抖動(dòng)加速python的實(shí)驗(yàn)仍在取得成果侦厚。其中包括一個(gè)微軟項(xiàng)目pyjion,它為cpython提供了一個(gè)JIT接口拙徽。微軟提供了自己的JIT作為概念證明刨沦。

8。升級(jí)至python 3

如果您使用的是python 2.x膘怕,并且沒(méi)有覆蓋的原因(比如不兼容的模塊)來(lái)堅(jiān)持使用它想诅,那么您應(yīng)該跳到python 3。

除了python 3作為語(yǔ)言的未來(lái)岛心,python 3中還提供了許多構(gòu)造和優(yōu)化来破,而python 2.x中沒(méi)有這些構(gòu)造和優(yōu)化。例如忘古,python 3.5通過(guò)將async和wait關(guān)鍵字作為語(yǔ)言語(yǔ)法的一部分來(lái)減少異步編程的麻煩徘禁。python 3.2對(duì)全局解釋器鎖進(jìn)行了重大升級(jí),顯著改進(jìn)了python處理多個(gè)線程的方式髓堪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末送朱,一起剝皮案震驚了整個(gè)濱河市娘荡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驶沼,老刑警劉巖炮沐,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異回怜,居然都是意外死亡大年,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)鹉戚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人专控,你說(shuō)我怎么就攤上這事抹凳。” “怎么了伦腐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵赢底,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我柏蘑,道長(zhǎng)幸冻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任咳焚,我火速辦了婚禮洽损,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘革半。我一直安慰自己碑定,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布又官。 她就那樣靜靜地躺著延刘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪六敬。 梳的紋絲不亂的頭發(fā)上碘赖,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音外构,去河邊找鬼普泡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛审编,可吹牛的內(nèi)容都是我干的劫哼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼割笙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼权烧!你這毒婦竟也來(lái)了眯亦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤般码,失蹤者是張志新(化名)和其女友劉穎妻率,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體板祝,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宫静,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了券时。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孤里。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖橘洞,靈堂內(nèi)的尸體忽然破棺而出捌袜,到底是詐尸還是另有隱情,我是刑警寧澤炸枣,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布虏等,位于F島的核電站,受9級(jí)特大地震影響适肠,放射性物質(zhì)發(fā)生泄漏霍衫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一侯养、第九天 我趴在偏房一處隱蔽的房頂上張望敦跌。 院中可真熱鬧,春花似錦逛揩、人聲如沸峰髓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)携兵。三九已至,卻和暖如春搂誉,著一層夾襖步出監(jiān)牢的瞬間徐紧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工炭懊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留并级,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓侮腹,卻偏偏與公主長(zhǎng)得像嘲碧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子父阻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容