欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

盤點提高 Python 代碼效率的方法

系統 1726 0

第一招:蛇打七寸:定位瓶頸

首先,第一步是定位瓶頸。舉個簡單的栗子,一個函數可以從1秒優化到到0.9秒,另一個函數可以從1分鐘優化到30秒,如果要花的代價相同,而且時間限制只能搞定一個,搞哪個?根據短板原理,當然選第二個啦。

一個有經驗的程序員在這里一定會遲疑一下,等等?函數?這么說,還要考慮調用次數?如果第一個函數在整個程序中需要被調用100000次,第二個函數在整個程序中被調用1次,這個就不一定了。舉這個栗子,是想說明,程序的瓶頸有的時候不一定一眼能看出來。還是上面那個選擇,程序員的你應該有感覺的,大多數情況下:一個「可以」從一分鐘優化到30秒的函數會比一個「可以」從1秒優化到0.9秒的函數更容易捕獲我們的注意,因為有很大的進步空間嘛。

所以,這么多廢話講完,獻上第一招,profile。這是 python 自帶的定位程序瓶頸的利器!雖然它提供了三種選項profile,cProfile,hotshot。還分為內置和外置。但是,個人覺得一種足矣,外置cProfile。心法如下:

            
python -m profile 逗比程序.py

          

這招的效果會輸出一系列東西,比如函數被調用了幾次,總時間多少,其中有多少是這個函數的子函數花費的,每次花多少時間,等等。嘛一圖勝千言:

filename:lineno(function): 文件名:第幾行(函數名)
ncalls: 這貨一共調用了幾次
tottime: 這貨自己總共花了多少時間,也就是要除掉內部函數小弟們的花費
percall: 平均每次調用花的時間,tottime 除以 ncalls
cumtime: 這貨還有它的所有內部函數小弟們的總花費
percall: 跟上面那個 percall 差不多,不過是 cumtime 除以 ncalls
找到最值得優化的點,然后干吧。

第二招:一蛇禪:只需一招

記得剛開始接觸 Python 的時候,有一位學長告訴我,Python 有一個牛逼的理想,它希望每一個用它的人能寫出一模一樣的程序。Python 之禪有云:

There should be one-- and preferably only one --obvious way to do it

所以 Python 系專業的禪師提供了一些常用功能的 only one 的寫法。本人看了一下傳說中的PythonWiKi:PerformanceTips,總結了幾個「不要醬紫」「要醬紫」。

合并字符串的時候不要醬紫:

            
s = "" for substring in list: s += substring

          

要醬紫:

            
s = "".join(slist)

          

格式化字符串的時候不要醬紫:

            
out = "" + head + prologue + query + tail + ""

          

要醬紫:

            
out = "%s%s%s%s" % (head, prologue, query, tail)

          

可以不用循環的時候就不要用循環,比如不要醬紫:

            
newlist = [] for word in oldlist: newlist.append(word.upper())

          

要醬紫:

            
newlist = map(str.upper, oldlist)

          

或者醬紫:

            
newlist = [s.upper() for s in oldlist]

          

字典初始化,比較常用的:

            
wdict = {} for word in words: if word not in wdict: wdict[word] = 0 wdict[word] += 1

          

如果重復的 word 太多了的話,可以考慮用醬紫的模式來省掉大量判斷:

            
wdict = {} for word in words: try: wdict[word] += 1 except KeyError: wdict[word] = 1

          

盡量減少 function 調用次數,用內部循環代替,比如,不要醬紫:

            
x = 0 def doit1(i): global x x = x + i list = range(100000) t = time.time() for i in list: doit1(i)

          

要醬紫:

            
x = 0 def doit2(list): global x for i in list: x = x + i list = range(100000) t = time.time() doit2(list)

          

第三招:蛇之狙擊:高速搜索

這一招部分來源于IBM:Python 代碼性能優化技巧,搜索算法的最高境界是O(1)的算法復雜度。也就是 Hash Table。本人幸本科的時候學了點數據結構。知道 Python 的 list 使用類似鏈表的方法實現的。如過列表很大的話,在茫茫多的項里面用 if X in list_a 來做搜索和判斷效率是非常低的。

Python 的 tuple 我用得非常少,不評論。另兩個我用得非常多的是 set 和 dict。這兩個就是用的類似 Hash Table 的實現方法。

所以盡量不要醬紫:

            
k = [10,20,30,40,50,60,70,80,90] for i in xrange(10000): if i in k: #Do something continue

          

要醬紫:

            
``` k = [10,20,30,40,50,60,70,80,90] k_dict = {i:0 for i in k}

          

先把 list 轉換成 dictionary

            
for i in xrange(10000): if i in k_dict: #Do something continue ```

          

找 list 的交集,不要醬紫:

            
list_a = [1,2,3,4,5]
list_b = [4,5,6,7,8]
list_common = [a for a in list_a if a in list_b]

          

要醬紫:

            
list_a = [1,2,3,4,5]
list_b = [4,5,6,7,8]
list_common = set(list_a)&set(list_b)

          

第四招:小蛇蛇……:想不出來名字了,就是各種小 Tips

變量交換不需要中間變量:a,b = b,a (這里有個神坑,至今記憶深刻:True,False = False,True)
如果使用 Python2.x,用 xrange 代替 range,如果用 Python3.x,range 已經是 xrange 了,xrange 已經木有了。xrange 不會像 range 一樣生成一個列表,而是生成一個迭代器,省內存。
可以用 x>y>z 代替 x>y and y>z。效率更高,可讀性也更好。當然理論上 x>y
add(x,y) 一般會比 a+b 要快?這個本人有所懷疑,實驗了一下,首先 add 不能直接用,要 import operator,第二,我的實驗結果表示 add(x,y) 完全沒有 a+b 快,更何況還要犧牲可讀性。
while 1 確實比 while True 要快那么一點點。做了兩次實驗,大概快了15%左右。
第五招:無蛇勝有蛇:代碼之外的性能

代碼之外嘛,除了硬件之外,就是編譯器了,這里隆重推薦 pypy。pypy是一種叫做 just-in-time 的即時編譯器。這個編譯器的特點就是編譯一句跑一句,和靜態的編譯器的區別嘛,我在知乎上看到一個非常形象的比喻:

假定你是一個導演,靜態編譯就是讓演員把整個劇本背下來吃透,然后連續表演一個小時。動態編譯就是讓演員表演兩分鐘,然后思考一下,再看一下劇本,再表演兩分鐘……

動態編譯和靜態編譯各有所長,看你演的是電影還是話劇了。

此外還有一個 Cython 可以在 python 里內置一些 C 的代碼。我用的非常少,但是關鍵時刻確實有效。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 看片国产 | 欧美在线视频免费看 | 91精品国产777在线观看 | 欧美一区二区在线播放 | 成人午夜免费福利 | 欧美日一区 | 亚洲人影院 | av网站免费看 | 亚洲一级视频在线观看 | 久久精品免费观看 | 伊人久久精品成人网 | 韩国精品一区二区 | 亚洲福利 | jizz视频| 亚洲一区欧美日韩 | 国产精品91久久久 | 国产二区在线播放 | 伊人情涩网 | 久久久久久久久久免观看 | 欧美成人观看视频在线 | 偷拍—91porny九色 | 啪啪免费视频网站 | 久久久9999久久精品小说 | 欧美网站www | 精品一区二区三区中文字幕 | 国产精品国产三级国产aⅴ入口 | 久久99精品视频 | 久久99精品这里精品动漫6 | 国99久9在线 | 免费 | 四虎影视最新网站在线播放 | 久久精品一区二区 | 播五月开心婷婷综合 | 欧美成人一区二区三区在线视频 | 亚洲精品无码成人A片在线虐 | 国产精品九九九久久九九 | 精品国产欧美一区二区 | 精品国产一区二区在线 | 色婷婷六月丁香在线观看 | 欧美在线观看一区 | 久久久无码精品亚洲日韩按摩 | 日韩中文一区二区三区 |