日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Python加速程序運(yùn)行的方法

瀏覽:21日期:2022-07-16 08:12:52

問題

你的程序運(yùn)行太慢,你想在不使用復(fù)雜技術(shù)比如C擴(kuò)展或JIT編譯器的情況下加快程序運(yùn)行速度。

解決方案

關(guān)于程序優(yōu)化的第一個(gè)準(zhǔn)則是“不要優(yōu)化”,第二個(gè)準(zhǔn)則是“不要優(yōu)化那些無關(guān)緊要的部分”。 如果你的程序運(yùn)行緩慢,首先你得使用14.13小節(jié)的技術(shù)先對它進(jìn)行性能測試找到問題所在。

通常來講你會(huì)發(fā)現(xiàn)你得程序在少數(shù)幾個(gè)熱點(diǎn)位置花費(fèi)了大量時(shí)間, 比如內(nèi)存的數(shù)據(jù)處理循環(huán)。一旦你定位到這些點(diǎn),你就可以使用下面這些實(shí)用技術(shù)來加速程序運(yùn)行。

使用函數(shù)

很多程序員剛開始會(huì)使用Python語言寫一些簡單腳本。 當(dāng)編寫腳本的時(shí)候,通常習(xí)慣了寫毫無結(jié)構(gòu)的代碼,比如:

# somescript.pyimport sysimport csvwith open(sys.argv[1]) as f: for row in csv.reader(f): # Some kind of processing pass

很少有人知道,像這樣定義在全局范圍的代碼運(yùn)行起來要比定義在函數(shù)中運(yùn)行慢的多。 這種速度差異是由于局部變量和全局變量的實(shí)現(xiàn)方式(使用局部變量要更快些)。 因此,如果你想讓程序運(yùn)行更快些,只需要將腳本語句放入函數(shù)中即可:

# somescript.pyimport sysimport csvdef main(filename): with open(filename) as f: for row in csv.reader(f): # Some kind of processing passmain(sys.argv[1])

速度的差異取決于實(shí)際運(yùn)行的程序,不過根據(jù)經(jīng)驗(yàn),使用函數(shù)帶來15-30%的性能提升是很常見的。

盡可能去掉屬性訪問

每一次使用點(diǎn)(.)操作符來訪問屬性的時(shí)候會(huì)帶來額外的開銷。 它會(huì)觸發(fā)特定的方法,比如 __getattribute__() 和 __getattr__() ,這些方法會(huì)進(jìn)行字典操作操作。

通常你可以使用 from module import name 這樣的導(dǎo)入形式,以及使用綁定的方法。 假設(shè)你有如下的代碼片段:

import mathdef compute_roots(nums): result = [] for n in nums: result.append(math.sqrt(n)) return result# Testnums = range(1000000)for n in range(100): r = compute_roots(nums)

在我們機(jī)器上面測試的時(shí)候,這個(gè)程序花費(fèi)了大概40秒。現(xiàn)在我們修改 compute_roots() 函數(shù)如下:

from math import sqrtdef compute_roots(nums): result = [] result_append = result.append for n in nums: result_append(sqrt(n)) return result

修改后的版本運(yùn)行時(shí)間大概是29秒。唯一不同之處就是消除了屬性訪問。 用 sqrt() 代替了 math.sqrt() 。 The result.append() 方法被賦給一個(gè)局部變量 result_append ,然后在內(nèi)部循環(huán)中使用它。

不過,這些改變只有在大量重復(fù)代碼中才有意義,比如循環(huán)。 因此,這些優(yōu)化也只是在某些特定地方才應(yīng)該被使用。

理解局部變量

之前提過,局部變量會(huì)比全局變量運(yùn)行速度快。 對于頻繁訪問的名稱,通過將這些名稱變成局部變量可以加速程序運(yùn)行。 例如,看下之前對于 compute_roots() 函數(shù)進(jìn)行修改后的版本:

import mathdef compute_roots(nums): sqrt = math.sqrt result = [] result_append = result.append for n in nums: result_append(sqrt(n)) return result

在這個(gè)版本中,sqrt 從 math 模塊被拿出并放入了一個(gè)局部變量中。 如果你運(yùn)行這個(gè)代碼,大概花費(fèi)25秒(對于之前29秒又是一個(gè)改進(jìn))。 這個(gè)額外的加速原因是因?yàn)閷τ诰植孔兞?sqrt 的查找要快于全局變量 sqrt

對于類中的屬性訪問也同樣適用于這個(gè)原理。 通常來講,查找某個(gè)值比如 self.name 會(huì)比訪問一個(gè)局部變量要慢一些。 在內(nèi)部循環(huán)中,可以將某個(gè)需要頻繁訪問的屬性放入到一個(gè)局部變量中。例如:

# Slowerclass SomeClass: ... def method(self): for x in s: op(self.value)# Fasterclass SomeClass: ... def method(self): value = self.value for x in s: op(value)

避免不必要的抽象

任何時(shí)候當(dāng)你使用額外的處理層(比如裝飾器、屬性訪問、描述器)去包裝你的代碼時(shí),都會(huì)讓程序運(yùn)行變慢。 比如看下如下的這個(gè)類:

class A: def __init__(self, x, y): self.x = x self.y = y @property def y(self): return self._y @y.setter def y(self, value): self._y = value

現(xiàn)在進(jìn)行一個(gè)簡單測試:

>>> from timeit import timeit>>> a = A(1,2)>>> timeit(’a.x’, ’from __main__ import a’)0.07817923510447145>>> timeit(’a.y’, ’from __main__ import a’)0.35766440676525235>>>

可以看到,訪問屬性y相比屬性x而言慢的不止一點(diǎn)點(diǎn),大概慢了4.5倍。 如果你在意性能的話,那么就需要重新審視下對于y的屬性訪問器的定義是否真的有必要了。 如果沒有必要,就使用簡單屬性吧。 如果僅僅是因?yàn)槠渌幊陶Z言需要使用getter/setter函數(shù)就去修改代碼風(fēng)格,這個(gè)真的沒有必要。

使用內(nèi)置的容器

內(nèi)置的數(shù)據(jù)類型比如字符串、元組、列表、集合和字典都是使用C來實(shí)現(xiàn)的,運(yùn)行起來非常快。 如果你想自己實(shí)現(xiàn)新的數(shù)據(jù)結(jié)構(gòu)(比如鏈接列表、平衡樹等), 那么要想在性能上達(dá)到內(nèi)置的速度幾乎不可能,因此,還是乖乖的使用內(nèi)置的吧。

避免創(chuàng)建不必要的數(shù)據(jù)結(jié)構(gòu)或復(fù)制

有時(shí)候程序員想顯擺下,構(gòu)造一些并沒有必要的數(shù)據(jù)結(jié)構(gòu)。例如,有人可能會(huì)像下面這樣寫:

values = [x for x in sequence]squares = [x*x for x in values]

也許這里的想法是首先將一些值收集到一個(gè)列表中,然后使用列表推導(dǎo)來執(zhí)行操作。 不過,第一個(gè)列表完全沒有必要,可以簡單的像下面這樣寫:

squares = [x*x for x in sequence]

與此相關(guān),還要注意下那些對Python的共享數(shù)據(jù)機(jī)制過于偏執(zhí)的程序所寫的代碼。 有些人并沒有很好的理解或信任Python的內(nèi)存模型,濫用 copy.deepcopy() 之類的函數(shù)。 通常在這些代碼中是可以去掉復(fù)制操作的。

討論

在優(yōu)化之前,有必要先研究下使用的算法。 選擇一個(gè)復(fù)雜度為 O(n log n) 的算法要比你去調(diào)整一個(gè)復(fù)雜度為 O(n**2) 的算法所帶來的性能提升要大得多。

如果你覺得你還是得進(jìn)行優(yōu)化,那么請從整體考慮。 作為一般準(zhǔn)則,不要對程序的每一個(gè)部分都去優(yōu)化,因?yàn)檫@些修改會(huì)導(dǎo)致代碼難以閱讀和理解。 你應(yīng)該專注于優(yōu)化產(chǎn)生性能瓶頸的地方,比如內(nèi)部循環(huán)。

你還要注意微小優(yōu)化的結(jié)果。例如考慮下面創(chuàng)建一個(gè)字典的兩種方式:

a = { ’name’ : ’AAPL’, ’shares’ : 100, ’price’ : 534.22}b = dict(name=’AAPL’, shares=100, price=534.22)

后面一種寫法更簡潔一些(你不需要在關(guān)鍵字上輸入引號)。 不過,如果你將這兩個(gè)代碼片段進(jìn)行性能測試對比時(shí),會(huì)發(fā)現(xiàn)使用 dict() 的方式會(huì)慢了3倍。 看到這個(gè),你是不是有沖動(dòng)把所有使用 dict() 的代碼都替換成第一種。 不夠,聰明的程序員只會(huì)關(guān)注他應(yīng)該關(guān)注的地方,比如內(nèi)部循環(huán)。在其他地方,這點(diǎn)性能損失沒有什么影響。

如果你的優(yōu)化要求比較高,本節(jié)的這些簡單技術(shù)滿足不了,那么你可以研究下基于即時(shí)編譯(JIT)技術(shù)的一些工具。 例如,PyPy工程是Python解釋器的另外一種實(shí)現(xiàn),它會(huì)分析你的程序運(yùn)行并對那些頻繁執(zhí)行的部分生成本機(jī)機(jī)器碼。 它有時(shí)候能極大的提升性能,通常可以接近C代碼的速度。 不過可惜的是,到寫這本書為止,PyPy還不能完全支持Python3. 因此,這個(gè)是你將來需要去研究的。你還可以考慮下Numba工程, Numba是一個(gè)在你使用裝飾器來選擇Python函數(shù)進(jìn)行優(yōu)化時(shí)的動(dòng)態(tài)編譯器。 這些函數(shù)會(huì)使用LLVM被編譯成本地機(jī)器碼。它同樣可以極大的提升性能。 但是,跟PyPy一樣,它對于Python 3的支持現(xiàn)在還停留在實(shí)驗(yàn)階段。

最后我引用John Ousterhout說過的話作為結(jié)尾:“最好的性能優(yōu)化是從不工作到工作狀態(tài)的遷移”。 直到你真的需要優(yōu)化的時(shí)候再去考慮它。確保你程序正確的運(yùn)行通常比讓它運(yùn)行更快要更重要一些(至少開始是這樣的).

以上就是Python加速程序運(yùn)行的方法的詳細(xì)內(nèi)容,更多關(guān)于Python加速程序運(yùn)行的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
福利一区二区三区视频在线观看| 欧美激情91| 麻豆精品少妇| 日韩av电影一区| 日韩精品视频一区二区三区| 亚洲精品系列| 日本aⅴ精品一区二区三区 | 国产欧美日韩免费观看| 日韩av中文字幕一区二区三区| 国产欧美一区二区三区国产幕精品 | 免费一区二区视频| 亚洲韩日在线| 婷婷综合激情| 亚洲精品a级片| 首页国产欧美久久| 三级久久三级久久久| 欧美天堂一区| 电影91久久久| 欧美日韩亚洲在线观看| 伊人精品视频| 日韩精品一页| 久久精品亚洲一区二区| 首页国产精品| 一区二区三区视频免费观看| 亚洲精品中文字幕乱码| 日韩视频一区| 亚洲婷婷丁香| 久久精品欧洲| 亚洲天堂成人| 亚洲精品日本| 精品视频亚洲| 午夜影院欧美| 欧美一区二区三区久久| 精品一二三区| 久久久影院免费| 亚洲综合专区| 国产成人在线中文字幕| 99国产精品久久久久久久成人热| 日本一不卡视频| 精品国产亚洲日本| 91精品推荐| 亚洲精品九九| 日韩国产综合| 免费观看在线综合色| 欧美精品二区| 午夜精品婷婷| 国产精品久久久网站| 久久久久久久久99精品大| 深夜日韩欧美| 日韩精品免费一区二区三区| 亚洲日产国产精品| 狠狠躁少妇一区二区三区| 石原莉奈一区二区三区在线观看| 国产精品自拍区| 激情婷婷欧美| 日本国产欧美| 亚洲不卡av不卡一区二区| 日本少妇精品亚洲第一区| 成人高清一区| 日韩中文字幕| 久久亚洲专区| 麻豆国产91在线播放| 国产美女精品| 欧美国产美女| 在线免费观看亚洲| a天堂资源在线| 亚洲aa在线| 99久久夜色精品国产亚洲1000部| 欧美专区一区| 午夜欧美精品久久久久久久| 国产精品视频首页| 午夜一区在线| 日韩欧美午夜| 日韩精品免费视频人成| 国产在线不卡| 国产福利电影在线播放| 欧美日韩视频免费看| 午夜久久一区| 日韩成人三级| 久久亚洲国产精品尤物| 色综合视频一区二区三区日韩| 伊伊综合在线| 久久在线91| 日韩国产在线不卡视频| 最新亚洲激情| 久久精品91| 国产精品观看| 日韩和欧美一区二区| 黄色在线一区| 午夜av成人| 精品成人18| 日本午夜精品久久久久| 国产精品色网| 国产综合婷婷| 日韩av首页| 国产夫妻在线| 精品免费av| 老色鬼精品视频在线观看播放| 色综合视频一区二区三区日韩 | 日本不卡中文字幕| 亚洲免费成人| 欧美亚洲国产精品久久| 精品国内亚洲2022精品成人| 亚洲影视一区| 蜜桃91丨九色丨蝌蚪91桃色| 欧美日韩国产在线观看网站| 日韩精品不卡一区二区| 欧美激情91| 91福利精品在线观看| 亚洲不卡视频| 中文字幕日本一区二区| 亚洲欧美高清| 中文日韩在线| 在线亚洲欧美| 日韩亚洲国产欧美| 国产精品美女久久久| 99日韩精品| 性色一区二区| 一区二区91| 亚洲精品一区二区在线播放∴| 日韩中文字幕麻豆| 免费看日韩精品| 日本欧洲一区二区| 久久亚洲图片| 亚洲精品在线二区| 日韩va亚洲va欧美va久久| 日韩国产精品久久久久久亚洲| 视频一区二区中文字幕| 视频一区中文字幕国产| 西西人体一区二区| 三级在线观看一区二区| 在线观看一区| 日韩精品国产欧美| 国产女人18毛片水真多18精品| 国产精品色在线网站| 麻豆91精品91久久久的内涵| 老司机免费视频一区二区| 亚洲ab电影| 欧美亚洲一级| 国产精品白丝av嫩草影院| 国产精品黄色| 久久电影tv| 激情欧美日韩一区| 国产亚洲亚洲| 九九综合九九| 欧美日韩视频一区二区三区| 女人av一区| 久久福利影视| 婷婷久久免费视频| 国产精品99精品一区二区三区∴| 欧美a在线观看| www.51av欧美视频| 超碰超碰人人人人精品| 亚洲网站视频| 亚洲一二三区视频| 国产福利一区二区精品秒拍 | 欧美日韩国产免费观看| 免费人成网站在线观看欧美高清| 日韩精品视频一区二区三区| 欧美1区2区3| 久久国产主播| 亚洲精品激情| 欧美精品中文字幕亚洲专区| 欧美亚洲专区| 欧美日韩视频网站| 亚洲欧美日韩一区在线观看| 欧美日韩一区二区三区四区在线观看 | 国产精品白浆| 亚洲啊v在线| 蜜桃av一区| 国产精品66| 亚洲午夜黄色| 偷拍亚洲精品| 欧洲av不卡| 日本欧美在线看| 精品久久免费| 午夜一级久久| 老司机免费视频一区二区| 欧美日韩第一| 国产美女视频一区二区| 欧美日韩一二三四| 国产调教精品| 欧美丝袜一区| 欧美亚洲国产日韩| 国产精品99免费看| 国产精品xvideos88| 1000部精品久久久久久久久| 亚洲精品黄色| 久久久久中文| 亚州av一区| 欧美精选视频一区二区| 日韩1区2区日韩1区2区| 国产精品高颜值在线观看| 人人精品人人爱| | 国产精品久久久久久久久久妞妞| 亚洲成av在线| 国产日韩欧美一区在线| 国产一区白浆| 成午夜精品一区二区三区软件|