中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python性能提升的方法有哪些

發布時間:2021-11-19 13:41:11 來源:億速云 閱讀:162 作者:iii 欄目:編程語言

本篇內容介紹了“Python性能提升的方法有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

時序分析

優化之前,首先要找到是哪部分代碼拖慢了整個程序的運行。有時候程序的"瓶頸"不是很明顯,如果找不到,以下是一些建議以供參考:

注意:這是一個計算e的x次冪的演示程序(出自Python文檔):

# slow_program.py  from decimal import*  defexp(x):      getcontext().prec +=2      i, lasts, s, fact, num =0, 0, 1, 1, 1      while s != lasts:          lasts = s          i +=1          fact *= i          num *= x          s += num / fact      getcontext().prec -=2      return+s  exp(Decimal(150))  exp(Decimal(400))  exp(Decimal(3000))

在GitHub上查看rawslow_program.py全部代碼

最省力的“性能分析”

首先,最簡單且最省力的解決方案是使用Unix的time命令: 

~ $ time python3.8  slow_program.py  real     0m11,058s  user     0m11,050s  sys      0m0,008s

在GitHub上查看rawbase_time.shell全部代碼

如果只是給整個程序計時,它很有用,但還不足夠……

最詳細的性能分析

性能分析的另一方法是cProfile,從中能得到很大的信息量:

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

在GitHub上查看rawcprofile.shell全部代碼

這里用cProfile模塊和time參數運行測試腳本,以便按內部時間(cumtime)對行進行排序。從中可以得到很多信息,以上所列結果約為實際輸出的10%。由此可見,exp函數就是拖慢程序的“罪魁禍首”(太神奇啦!),現在看看更詳盡的時序和性能分析......

對特定函數計時

已經知道拖慢程序運行的函數,下一步可使用簡單的修飾器,專門對該函數計時,不測量其余代碼。如下所示:

deftimeit_wrapper(func):      @wraps(func)      defwrapper(*args, **kwargs):          start =  time.perf_counter()  # Alternatively, you  can use time.process_time()          funcfunc_return_val = func(*args, **kwargs)          end = time.perf_counter()          print( {0:<10}.{1:<8} : {2:<8} .format(func.__module__, func.__name__, end - start))          return func_return_val      return wrapper

在GitHub上查看rawtimeit_decorator.py全部代碼

該修飾器可以應用于功能測試,如下所示:

@timeit_wrapper  defexp(x):      ...  print( {0:<10}{1:<8}{2:^8} .format( module ,  function ,  time ))  exp(Decimal(150))  exp(Decimal(400))  exp(Decimal(3000))

在GitHub上查看rawtimeit_decorator_usage.py全部代碼

輸出如下: 

~ $ python3.8  slow_program.py  module     function   time     __main__  .exp       :0.003267502994276583  __main__  .exp       :0.038535295985639095  __main__  .exp       : 11.728486061969306

在GitHub上查看rawrun_with_timeit_decorator.shell全部代碼

要考慮的一個問題是實際/想要測量的時間類型是什么。Time程序包提供了time.perf_counter和time.process_time。兩者的區別是:perf_counter返回絕對值,其中包括Python程序進程未運行時的時間,因此可能會受計算機負載的影響;而process_time僅返回用戶時間(不包括系統時間),這僅是程序的運行時間。

加快程序運行速度這是全文有趣的部分,關于如何加快Python的程序運行速度。我并沒有列出一些可以奇妙解決性能問題的小技巧或代碼段,而是涉及一般性的構想和策略,它們能極大地提高性能,某些情況下甚至能將性能提高30%。

使用內置數據類型

顯而易見,內置數據類型運行很快,尤其是與自定義類型(例如樹或鏈表)相比。主要是因為內置程序是用C語言實現的,遠超過用Python編碼的運行速度。

使用lru_cache緩存/記憶 

我已經在上一篇博文中講過這塊內容,但在此還是要用簡單的示例說明:

import functools  import time  # caching up to 12  different results  @functools.lru_cache(maxsize=12)  defslow_func(x):      time.sleep(2)  # Simulate long computation      return x  slow_func(1)  # ... waiting for 2 sec before getting  result  slow_func(1)  # already cached - result returned  instantaneously!  slow_func(3)  # ... waiting for 2 sec before getting  result

在GitHub上查看rawlru_cache.py全部代碼

以上函數使用time.sleep模擬大量運算。第一次使用參數1調用該函數時,返回結果需要2秒。再次調用時,結果已被緩存,因此會跳過函數主體并立即返回結果。更多內容請參見此處。

使用局部變量

這與在每個作用域中查找變量的速度有關。我用了“每個作用域”這個字眼,因為它不僅僅是“使用局部變量還是全局變量”的問題。實際上,即使在函數的局部變量(最快)、類級屬性(如self.name-較慢)和全局變量(如導入的函數,time.time-最慢)之間,查找速度也有所不同。

可以通過運行無用的任務來提高性能,如下所示:

#  Example #1  classFastClass:      defdo_stuff(self):          temp =self.value  # this speeds up lookup in loop          for i inrange(10000):              ...  # Do something with `temp` here  #  Example #2  import random  deffast_function():      r = random.random      for i inrange(10000):          print(r())  # calling `r()` here, is faster than  global random.random()

在GitHub上查看rawlocal_vars.py全部代碼

使用函數(Function)

這怎么和假想的不同?理論上調用函數不是會將更多的東西放到堆棧上,加大返回結果的負擔嗎?但實際上,使用函數確實能加快運行速度,這與前一點有關。將整個代碼放在一個文件中而非函數中,它是全局變量而非局部變量,運行速度就會慢得多。因此,可以將整個代碼包裹在main函數中并通過一次調用來加速代碼,如下所示:

defmain():      ...  # All your previously global code  main()

在GitHub上查看rawglobal_vars.py全部代碼

避免訪問屬性(Attribute)

可能拖慢程序的一個原因是使用點運算符(.)訪問對象屬性。該運算符通過使用__getattribute__方法觸發了字典查找,使代碼產生額外負擔。那么,如何避免或減少屬性訪問? 

#  Slow:  import re  defslow_func():      for i inrange(10000):          re.findall(regex, line)  # Slow!  #  Fast:  from re import findall  deffast_func():      for i inrange(10000):          findall(regex, line)  # Faster!

在GitHub上查看rawimports.py全部代碼

當心使用字符串

在循環里使用格式符(%s)或.format()時,字符串操作可能會變得非常慢。有沒有更好的選擇?Raymond Hettinger在最近發布的推文中提到:唯一應該使用的是f-string(格式化字符串常量),它是最易讀、最簡潔且最快捷的方法。根據這篇推文,下面列出了可用的方法(由快到慢):

f {s}{t}   # Fast!  s +    + t     .join((s, t))   %s %s % (s, t)   {} {} .format(s, t)  Template( $s $t ).substitute(ss=s, tt=t)  # Slow!

在GitHub上查看rawstrings.py全部代碼

本質上,生成器并沒有變得更快,因為它在設計上允許延遲計算以節省內存而非節約時間。然而節省的內存也可以加快程序實際運行速度。怎么做?如果有一個很大的數據集且不使用生成器(迭代器),那么數據可能會溢出CPU的L1 cache(1級緩存),這將大大減慢內存的查找速度。

在性能方面,極重要的一點是:CPU可以將正在處理的所有數據盡可能地保存在緩存中。

“Python性能提升的方法有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阳泉市| 慈溪市| 车险| 弥勒县| 浪卡子县| 丰台区| 托里县| 泰兴市| 五原县| 利津县| 安塞县| 新建县| 屏东县| 霍林郭勒市| 东乡族自治县| 宁南县| 哈密市| 辉南县| 儋州市| 隆德县| 丰镇市| 石林| 农安县| 怀柔区| 原平市| 普兰店市| 双辽市| 洪泽县| 民丰县| 巫山县| 五峰| 姚安县| 南部县| 菏泽市| 灵璧县| 甘肃省| 武冈市| 遵化市| 会昌县| 红原县| 蓬安县|