精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

【進階】嫌棄Python慢,試試這幾個方法?

開發 后端
優化的第一要義就是「不要去做」。但如果你必須要做,我希望這些小技巧可以幫助到你。然而,優化代碼時一定要謹慎,因為該操作可能最終造成代碼可讀性變差、可維護性變差,這些弊端可能超過代碼優化所帶來的好處。

【進階】嫌棄Python慢,試試這幾個方法?

計時與性能分析

在開始優化之前,我們首先需要找到代碼的哪一部分真正拖慢了整個程序。有時程序性能的瓶頸顯而易見,但當你不知道瓶頸在何處時,這里有一些幫助找到性能瓶頸的辦法:

注:下列程序用作演示目的,該程序計算 e 的 X 次方(摘自 Python 文檔):

  1. # slow_program.py 
  2. from decimal import * 
  3.  
  4. def exp(x): 
  5.     getcontext().prec += 2 
  6.     i, lasts, s, fact, num = 0, 0, 1, 1, 1 
  7.     while s != lasts: 
  8.         lasts = s 
  9.         i += 1 
  10.         fact *= i 
  11.         num *= x 
  12.         s += num / fact 
  13.     getcontext().prec -= 2 
  14.     return +s 
  15.  
  16. exp(Decimal(150)) 
  17. exp(Decimal(400)) 
  18. exp(Decimal(3000)) 

最懶惰的「性能分析」

首先,最簡單但說實話也很懶的方法——使用 Unix 的 time 命令:

  1. ~ $ time python3.8 slow_program.py 
  2.  
  3. real    0m11,058s 
  4. user    0m11,050s 
  5. sys     0m0,008s 

如果你只想給整個程序計時,這個命令即可完成目的,但通常是不夠的……

最細致的性能分析

另一個極端是 cProfile,它提供了「太多」的信息:

  1. ~ $ python3.8 -m cProfile -s time slow_program.py 
  2.          1297 function calls (1272 primitive calls) in 11.081 seconds 
  3.  
  4.    Ordered by: internal time 
  5.  
  6.    ncalls  tottime  percall  cumtime  percall filename:lineno(function
  7.         3   11.079    3.693   11.079    3.693 slow_program.py:4(exp) 
  8.         1    0.000    0.000    0.002    0.002 {built-in method _imp.create_dynamic} 
  9.       4/1    0.000    0.000   11.081   11.081 {built-in method builtins.exec
  10.         6    0.000    0.000    0.000    0.000 {built-in method __new__ of type object at 0x9d12c0} 
  11.         6    0.000    0.000    0.000    0.000 abc.py:132(__new__) 
  12.        23    0.000    0.000    0.000    0.000 _weakrefset.py:36(__init__) 
  13.       245    0.000    0.000    0.000    0.000 {built-in method builtins.getattr} 
  14.         2    0.000    0.000    0.000    0.000 {built-in method marshal.loads} 
  15.        10    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:1233(find_spec) 
  16.       8/4    0.000    0.000    0.000    0.000 abc.py:196(__subclasscheck__) 
  17.        15    0.000    0.000    0.000    0.000 {built-in method posix.stat} 
  18.         6    0.000    0.000    0.000    0.000 {built-in method builtins.__build_class__} 
  19.         1    0.000    0.000    0.000    0.000 __init__.py:357(namedtuple) 
  20.        48    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:57(_path_join) 
  21.        48    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:59(<listcomp>) 
  22.         1    0.000    0.000   11.081   11.081 slow_program.py:1(<module>) 
  23. ... 

這里,我們結合 cProfile 模塊和 time 參數運行測試腳本,使輸出行按照內部時間(cumtime)排序。這給我們提供了大量信息,上面你看到的行只是實際輸出的 10%。從輸出結果我們可以看到 exp 函數是罪魁禍首(驚不驚喜,意不意外),現在我們可以更加專注于計時和性能分析了……

計時專用函數

現在我們知道了需要關注哪里,那么我們可能只想要給運行緩慢的函數計時而不去管代碼的其他部分。我們可以使用一個簡單的裝飾器來做到這點:

  1. def timeit_wrapper(func): 
  2.     @wraps(func) 
  3.     def wrapper(*args, **kwargs): 
  4.         start = time.perf_counter()  # Alternatively, you can use time.process_time() 
  5.         func_return_val = func(*args, **kwargs) 
  6.         end = time.perf_counter() 
  7.         print('{0:<10}.{1:<8} : {2:<8}'.format(func.__module__, func.__name__, end - start)) 
  8.         return func_return_val 
  9.     return wrapper 

接著,將該裝飾器按如下方式應用在待測函數上:

  1. @timeit_wrapper 
  2. def exp(x): 
  3.     ... 
  4.  
  5. print('{0:<10} {1:<8} {2:^8}'.format('module''function''time')) 
  6. exp(Decimal(150)) 
  7. exp(Decimal(400)) 
  8. exp(Decimal(3000)) 

得到如下輸出:

  1. ~ $ python3.8 slow_program.py 
  2. module     function   time   
  3. __main__  .exp      : 0.003267502994276583 
  4. __main__  .exp      : 0.038535295985639095 
  5. __main__  .exp      : 11.728486061969306 

此時我們需要考慮想要測量哪一類時間。time 庫提供了 time.perf_counter 和 time.process_time 兩種時間。其區別在于,perf_counter 返回絕對值,其中包括了 Python 程序并不在運行的時間,因此它可能受到機器負載的影響。而 process_time 只返回用戶時間(除去了系統時間),也就是只有進程運行時間。

讓程序更快

現在到了真正有趣的部分了,讓 Python 程序跑得更快!我不會告訴你一些奇技淫巧或代碼段來神奇地解決程序的性能問題,而更多是關于通用的想法和策略。使用這些策略,可以對程序性能產生巨大的影響,有時甚至可以帶來高達 30% 的提速。

使用內置的數據類型

這一點非常明顯。內置的數據類型非常快,尤其相比于樹或鏈表等自定義類型而言。這主要是因為內置數據類型使用 C 語言實現,使用 Python 實現的代碼在運行速度上和它們沒法比。

使用 lru_cache 實現緩存/記憶

我在之前的博客中介紹過這一技巧,但我認為它值得用一個簡單例子再次進行說明:

  1. import functools 
  2. import time 
  3.  
  4. # caching up to 12 different results 
  5. @functools.lru_cache(maxsize=12) 
  6. def slow_func(x): 
  7.     time.sleep(2)  # Simulate long computation 
  8.     return x 
  9.  
  10. slow_func(1)  # ... waiting for 2 sec before getting result 
  11. slow_func(1)  # already cached - result returned instantaneously! 
  12.  
  13. slow_func(3)  # ... waiting for 2 sec before getting result 

上面的函數使用 time.sleep 模擬了繁重的計算過程。當我們第一次使用參數 1 調用函數時,它等待了 2 秒鐘后返回了結果。當再次調用時,結果已經被緩存起來,所以它跳過了函數體,直接返回結果。

使用局部變量

這和每個作用域中變量的查找速度有關。我之所以說「每個作用域」,是因為這不僅僅關乎局部變量或全局變量。事實上,就連函數中的局部變量、類級別的屬性和全局導入函數這三者的查找速度都會有區別。函數中的局部變量最快,類級別屬性(如 self.name)慢一些,全局導入函數(如 time.time)最慢。

你可以通過這種看似沒有必要的代碼組織方式來提高效率:

  1. #  Example #1 
  2. class FastClass: 
  3.  
  4.     def do_stuff(self): 
  5.         temp = self.value  # this speeds up lookup in loop 
  6.         for i in range(10000): 
  7.             ...  # Do something with `temp` here 
  8.  
  9. #  Example #2 
  10. import random 
  11.  
  12. def fast_function(): 
  13.     r = random.random 
  14.     for i in range(10000): 
  15.         print(r())  # calling `r()` here, is faster than global random.random() 

使用函數

這也許有些反直覺,因為調用函數會讓更多的東西入棧,進而在函數返回時為程序帶來負擔,但這其實和之前的策略相關。如果你只是把所有代碼扔進一個文件而沒有把它們放進函數,那么它會因為眾多的全局變量而變慢。因此,你可以通過將所有代碼封裝在 main 函數中并調用它來實現加速,如下所示:

  1. def main(): 
  2.     ...  # All your previously global code 
  3.  
  4. main() 

不要訪問屬性

另一個可能讓程序變慢的東西是用來訪問對象屬性的點運算符(.)。這個運算符會引起程序使用__getattribute__進行字典查找,進而為程序帶來不必要的開銷。那么,我們怎么避免(或者限制)使用它呢?

  1. #  Slow: 
  2. import re 
  3.  
  4. def slow_func(): 
  5.     for i in range(10000): 
  6.         re.findall(regex, line)  # Slow! 
  7.  
  8. #  Fast: 
  9. from re import findall 
  10.  
  11. def fast_func(): 
  12.     for i in range(10000): 
  13.         findall(regex, line)  # Faster! 

當心字符串

當在循環中使用取模運算符(%s)或 .format() 時,字符串操作會變得很慢。有沒有更好的選擇呢?根據 Raymond Hettinger 近期發布的推文,我們只需要使用 f-string 即可,它可讀性更強,代碼更加緊湊,并且速度更快!基于這一觀點,如下從快到慢列出了你可以使用的一系列方法:

  1. f'{s} {t}'  # Fast! 
  2. s + '  ' + t  
  3. ' '.join((s, t)) 
  4. '%s %s' % (s, t)  
  5. '{} {}'.format(s, t) 
  6. Template('$s $t').substitute(s=s, t=t)  # Slow! 

生成器本質上并不會更快,因為它們的目的是惰性計算,以節省內存而非節省時間。然而,節省的內存會讓程序運行更快。為什么呢?如果你有一個大型數據集,并且你沒有使用生成器(迭代器),那么數據可能造成 CPU 的 L1 緩存溢出,進而導致訪存速度顯著變慢。

當涉及到效率時,非常重要的一點是 CPU 會將它正在處理的數據保存得離自己越近越好,也就是保存在緩存中。讀者可以看一看 Raymond Hettingers 的演講(https://www.youtube.com/watch?v=OSGv2VnC0go&t=8m17s),其中提到了這些問題。

總結

優化的第一要義就是「不要去做」。但如果你必須要做,我希望這些小技巧可以幫助到你。然而,優化代碼時一定要謹慎,因為該操作可能最終造成代碼可讀性變差、可維護性變差,這些弊端可能超過代碼優化所帶來的好處。 

責任編輯:龐桂玉 來源: 機器學習算法與Python學習
相關推薦

2018-04-18 06:56:26

iPhone手機電量

2022-11-08 08:53:56

插件IDE

2020-12-07 10:59:01

Python數據工具

2022-11-11 17:06:43

開發組件工具

2021-02-23 18:38:11

iPhone地圖蘋果

2022-09-26 12:17:14

clamp() 函數CSS

2018-12-14 15:51:47

Pandas數據數據結構

2019-02-28 20:20:43

Python技巧編程語言

2018-03-20 16:03:00

鼠標方法硬件

2024-11-08 13:24:43

2022-04-12 08:43:21

Python內置模塊

2022-04-28 23:08:40

Windows 10微軟功能

2024-06-03 08:52:40

2023-10-07 08:59:02

2022-08-29 08:41:52

異步ControllerrunAsync

2019-10-10 09:34:19

Python網絡爬蟲GitHub

2020-07-03 18:14:20

JavaScript開發技術

2021-06-11 13:59:22

CSS原子類

2021-10-27 10:07:59

GitHub代碼開發者

2020-02-03 09:29:32

JavaScript代碼斷點
點贊
收藏

51CTO技術棧公眾號

日韩欧美黄色| 在线观看一区欧美| 亚洲人与黑人屁股眼交| 久久人体av| 一区二区三区高清在线| 亚洲自拍偷拍区| 亚洲黄色三级视频| 大片网站久久| 精品久久久久久久久久久久久久久久久 | 18在线观看的| 成人一区在线看| 欧美专区在线播放| 亚洲伦理一区二区三区| 都市激情亚洲| 欧美日韩视频在线一区二区 | 免费黄色在线播放| 成人软件在线观看| 亚洲免费av观看| 精品无码久久久久久久动漫| 日韩熟女一区二区| 永久亚洲成a人片777777| 日韩精品免费在线视频观看| 天天操狠狠操夜夜操| 国产精品论坛| 一区二区三区四区在线免费观看| 精品免费国产| 亚洲精品中文字幕成人片| 日本sm残虐另类| 尤物tv国产一区| 在线免费观看av的网站| 日韩欧美精品一区二区三区| 一区二区三区在线视频观看58 | 精品视频亚洲| 亚洲国产成人精品电影| 国产性生活一级片| 成人亚洲综合| 色综合久久中文字幕| 男人草女人视频| 免费看a在线观看| 国产亚洲综合在线| 999视频在线观看| 91午夜交换视频| 蜜臀av一区二区三区| 国产成人精品久久| 国产成人无码精品亚洲| 91久久亚洲| 久久久久久久久久久免费精品| 女人18毛片毛片毛片毛片区二| 欧美精选视频在线观看| 国产性色av一区二区| 中文字幕第3页| aaa国产精品| 日韩一区二区在线观看视频播放| 久热在线视频观看| 亚洲视频自拍| 91精品国产麻豆国产自产在线| 亚洲怡红院在线| 95精品视频| 日韩美女视频一区二区在线观看| 天堂av手机在线| 蜜桃精品视频| 欧美日韩一区国产| 久久精品久久99| 久久亚洲中文字幕无码| 国产永久免费视频| 国内外成人在线| 亚洲自拍偷拍福利| 亚洲乱码国产乱码精品精软件| 美女脱光内衣内裤视频久久网站 | 视频一区二区视频| caopon在线免费视频| 尤物视频一区二区| 日韩xxxx视频| 欧产日产国产精品视频| 午夜精品福利视频网站| 丁香六月激情网| 国产蜜臀一区二区打屁股调教| 亚洲日本va午夜在线影院| 黄色a级在线观看| 在线你懂的视频| 亚洲一卡二卡三卡四卡| 精品久久一二三| 中文字幕资源网在线观看免费| 在线视频一区二区三| 五月天激情播播| 凹凸av导航大全精品| 亚洲开心激情网| 欧美视频一区二区在线| 国产精品激情| 国产成人黄色av| 国产高清不卡视频| 成人av网站在线| 99久久精品久久久久久ai换脸| 国产精品区在线观看| 亚洲人成高清| 国产精品美女在线| 国产免费av电影| 成人免费看的视频| 亚洲成人第一| 182在线播放| 精品视频资源站| 中文字幕永久免费| 精品72久久久久中文字幕| 久久中文字幕在线| 国产一级淫片a视频免费观看| 成人激情四射网| 亚洲精品男同| 成人精品一区二区三区电影黑人| 蜜臀av中文字幕| 中文字幕在线一区免费| 日韩欧美一区三区| 日韩五码电影| 亚洲色图25p| 久久精品国产亚洲AV无码男同| 蜜臀va亚洲va欧美va天堂| 久久99精品久久久久久水蜜桃| 日韩精品黄色| 色婷婷综合久久| 天美一区二区三区| 日韩系列欧美系列| 欧美一级成年大片在线观看 | 精品处破学生在线二十三| 激情五月深爱五月| 亚洲大片av| av资源一区二区| 生活片a∨在线观看| 精品久久久久久久久久久| 欧美激情第一区| 色999日韩| 日本中文字幕成人| 手机福利在线| 日韩av自拍偷拍| 男女视频网站在线观看| 国产素人视频在线观看| 亚洲精品成人悠悠色影视| 国产又大又黄又猛| 精品国产91久久久久久浪潮蜜月| 97精品国产aⅴ7777| www.看毛片| 亚洲欧洲成人精品av97| 一区二区三区 日韩| 亚洲精品国产setv| 久久精品视频播放| 国产精品欧美亚洲| 亚洲免费观看高清在线观看| 丁香婷婷激情网| 女人丝袜激情亚洲| 日本免费久久高清视频| 四虎精品成人影院观看地址| 精品久久香蕉国产线看观看亚洲| 九九热免费在线观看| 99精品在线观看| 国产一区观看| 欧美成人午夜激情| 国产乱淫片视频| 综合在线观看色| 亚洲欧美在线精品| 日韩精品中文字幕第1页| 欧美亚洲国产成人精品| 国产在线观看网站| 欧美亚洲国产bt| 国产精品精品软件男同| 韩国一区二区三区| 国产一级不卡视频| 精品av导航| 日韩免费精品视频| 高清性色生活片在线观看| 欧美日韩三级一区二区| av电影在线播放| 国产一区二区你懂的| 精品一区二区日本| 在线成人av观看| 一本色道久久88综合亚洲精品ⅰ| 中文字幕av资源| 亚洲欧美国产77777| 人妻体体内射精一区二区| 亚洲福利免费| 欧洲在线视频一区| **国产精品| 久久福利视频导航| 天天综合天天综合| 欧美视频在线播放| 麻豆亚洲av熟女国产一区二| 97久久超碰精品国产| 激情视频免费网站| 在线看片欧美| 久久狠狠久久综合桃花| 美女写真久久影院| 九色91av视频| 丝袜+亚洲+另类+欧美+变态| 欧美日韩小视频| 日韩视频免费观看高清| 国产偷国产偷亚洲高清人白洁| 天天干天天色天天干| 日韩午夜精品| 亚洲精品偷拍视频| 哺乳挤奶一区二区三区免费看| 91成人免费观看网站| 日本三级视频在线观看| 日韩精品一区二区视频| 91chinesevideo永久地址| 国产jzjzjz丝袜老师水多| 日韩欧美国产网站| 亚洲av鲁丝一区二区三区| www.日韩av| 精品综合久久久久| 午夜一区不卡| 欧美黑人在线观看| 欧美xxxxx视频| 成人精品在线观看| 欧美影视资讯| 欧美亚洲成人网| 日韩激情av| 日韩视频精品在线| 毛片免费在线观看| 精品国产一二三区| 国产精品福利电影| 亚洲精品日韩一| 久久视频一区二区三区| 2023国产精品| 日本69式三人交| 久久成人精品无人区| 久久久久久久久久久久久国产精品| 欧美成人精品| 中文字幕乱码一区二区三区| 一区二区导航| 久久涩涩网站| 亚洲欧美综合久久久久久v动漫| 国产999在线观看| 水蜜桃在线视频| 97国产精品视频| 免费毛片b在线观看| 欧美大奶子在线| 九色porny在线| 日韩在线视频导航| 香蕉视频在线播放| 自拍偷拍亚洲区| 国产视频精品久久| 亚洲欧美精品一区二区| 日韩美女一级视频| 日韩欧美国产午夜精品| 国产熟女一区二区丰满| 欧美日韩dvd在线观看| 自拍偷拍福利视频| 欧美在线免费观看视频| 亚洲 国产 日韩 欧美| 在线视频欧美区| av首页在线观看| 欧美日韩中文字幕一区二区| 一级黄色在线视频| 在线欧美小视频| 日本视频www色| 在线中文字幕一区二区| 伊人久久中文字幕| 欧美日韩精品欧美日韩精品一综合| 日韩一区二区精品视频| 深夜福利视频网站| 亚洲跨种族黑人xxx| 二区在线观看| 一区三区二区视频| av在线播放av| 不卡av日日日| f2c人成在线观看免费视频| 2019中文字幕在线| 色吧亚洲日本| 国产精品自在线| 精品久久国产一区| 亚洲自拍av在线| 国产精品极品国产中出| 国产视频在线观看一区| 欧美激情在线精品一区二区三区| 好吊色欧美一区二区三区四区 | 91手机视频在线观看| 亚洲图色一区二区三区| 九色91视频| 国产精品嫩模av在线| 视频在线精品一区| 午夜日韩福利| 北条麻妃在线视频| 狠狠色狠狠色合久久伊人| 日本不卡视频一区| 国产午夜一区二区三区| 农村黄色一级片| 色天使色偷偷av一区二区| 这里只有精品6| 69堂成人精品免费视频| 蜜桃91麻豆精品一二三区| 亚洲视频777| 手机在线免费看av| 国产精品99久久久久久人| 国产亚洲观看| 精品免费国产| 午夜久久美女| 丰满少妇在线观看| 成人免费看的视频| 欧美一区二区三区观看| 香蕉影视欧美成人| 一级特黄免费视频| 亚洲第一色在线| 岛国在线视频| 91av在线免费观看| 日本综合精品一区| 精品国产91亚洲一区二区三区www| 久久一区二区三区电影| 伊人成色综合网| 国产精品一区三区| 天天操天天舔天天射| 中文成人av在线| 激情视频在线播放| 欧美亚洲综合另类| 欧美视频免费一区二区三区| 欧美另类交人妖| 成人在线免费av| 国产一区二区黄色| 欧美日本三区| 国产精品18毛片一区二区| 一级黄色在线观看| 欧美探花视频资源| 日本1级在线| 中文字幕精品av| 精精国产xxxx视频在线中文版 | 区一区二在线观看| 精品成人一区二区| yiren22综合网成人| 欧美在线视频免费观看| 高清欧美性猛交xxxx黑人猛| 亚洲视频在线二区| 国产视频亚洲| 成人性生活免费看| 亚洲国产综合人成综合网站| 中文字幕在线视频免费| 亚洲小视频在线观看| 神马久久午夜| 不卡一区二区三区视频| 亚洲欧美色图| 日本xxxxxxx免费视频| 久久综合久色欧美综合狠狠| 久久高清免费视频| 精品国产一区二区亚洲人成毛片| av在线播放国产| 91免费欧美精品| 一本到12不卡视频在线dvd| 在线不卡一区二区三区| 91在线看国产| 天堂а√在线中文在线新版| 日韩欧美电影一二三| 欧美性受ⅹ╳╳╳黑人a性爽| 91在线视频成人| 欧美激情成人在线| 极品白嫩的小少妇| 午夜精品一区在线观看| 殴美一级特黄aaaaaa| 97在线观看免费| 性人久久久久| 韩国中文字幕av| 国产精品电影院| 国产日韩一级片| 久久久www成人免费精品| 精品国产不卡一区二区| av一区二区三区免费观看| 成人免费电影视频| 国产精品视频免费播放| 亚洲欧美在线磁力| 日本韩国欧美| 在线观看日韩片| 国产激情精品久久久第一区二区 | 欧美网站大全在线观看| 日本高清视频在线观看| 国产精品久久久久久久久久久久久久 | 中文字幕一区二区三区四区五区六区| 日韩视频免费| 五月天综合视频| 色美美综合视频| 天天操天天操天天| 欧美亚洲视频在线观看| 热久久天天拍国产| 日本特黄在线观看| 亚洲自拍偷拍综合| 亚洲av永久纯肉无码精品动漫| 国内免费精品永久在线视频| 欧美美女在线| 日本一二三区在线| 欧美日韩激情视频| 免费在线视频欧美| 国产精品伊人日日| 日本美女一区二区三区视频| www.超碰在线观看| 亚洲欧美日韩天堂| 国产一区二区三区黄网站| 国产婷婷一区二区三区| 国产精品系列在线| 色婷婷av一区二区三区之红樱桃 | 亚洲va在线观看| 日韩中文字幕在线免费观看| 免费日韩一区二区三区| mm131亚洲精品| 亚洲国产日产av| 一级毛片视频在线| 精品无人乱码一区二区三区的优势 | 国语自产精品视频在线看一大j8|