国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python性能分析工具pyinstrument快速定位最慢的代碼

Python性能分析工具pyinstrument快速定位最慢的代碼

2021-09-09 00:05Python七號somenzz Python

今天分享一個超級實用的 Python 性能分析工具 pyinstrument ,可以快速找到代碼運行最慢的部分,幫助提高代碼的性能。支持 Python 3.7+ 且能夠分析異步代碼,僅需一條命令即可顯示具體代碼的耗時。

Python性能分析工具pyinstrument快速定位最慢的代碼

天下武功,唯快不破。

編程也不例外,你的代碼跑的快,你能快速找出代碼慢的原因,你的碼功就高。

今天分享一個超級實用的 Python 性能分析工具 pyinstrument ,可以快速找到代碼運行最慢的部分,幫助提高代碼的性能。支持 Python 3.7+ 且能夠分析異步代碼,僅需一條命令即可顯示具體代碼的耗時。經常寫 Python 的小伙伴一定要用一下。

安裝

  1. pip install pyinstrument 

簡單的使用

在程序的開始,啟動 pyinstrument 的 Profiler,結束時關閉 Profiler 并打印分析結果如下:

  1. from pyinstrument import Profiler 
  2.  
  3. profiler = Profiler() 
  4. profiler.start() 
  5.  
  6. # 這里是你要分析的代碼 
  7.  
  8. profiler.stop() 
  9.  
  10. profiler.print() 

比如這段代碼 123.py,我們可以清楚的看到是列表推導式比較慢:

  1. from pyinstrument import Profiler 
  2.  
  3. profiler = Profiler() 
  4. profiler.start() 
  5.  
  6. # 這里是你要分析的代碼 
  7. a = [i for i in range(100000)] 
  8. b = (i for i in range(100000)) 
  9.  
  10. profiler.stop() 
  11. profiler.print() 

Python性能分析工具pyinstrument快速定位最慢的代碼

上述分析需要修改源代碼,如果你使用命令行工具,就不需要修改源代碼,只需要執行 pyinstrument xxxx.py 即可:

比如有這樣一段排序的程序 c_sort.py:

  1. import sys 
  2. import time 
  3.  
  4. import numpy as np 
  5.  
  6. arr = np.random.randint(0, 10, 10) 
  7.  
  8. def slow_key(el): 
  9.     time.sleep(0.01) 
  10.     return el  
  11.  
  12. arr = list(arr) 
  13.  
  14. for i in range(10): 
  15.     arr.sort(key=slow_key) 
  16.  
  17. print(arr) 

這段代碼里面故意放了一句 time.sleep(0.01) 來延遲性能,看看 pyinstrument 能否識別,命令行執行 pyinstrument c_sort.py:

Python性能分析工具pyinstrument快速定位最慢的代碼

從結果來看,程序運行了 1.313 秒,而 sleep 就運行了 1.219 秒,很明顯是瓶頸,現在我們把它刪除,再看看結果:

Python性能分析工具pyinstrument快速定位最慢的代碼

刪除之后,性能最慢的就是 numpy 模塊的初始化代碼 __init__.py了,不過這些代碼不是自己寫的,而且并不是特別慢,就不需要去關心了。

分析 Flask 代碼

Web 應用也可以使用這個來找出性能瓶頸,比如 flask,只需要在請求之前記錄時間,在請求之后統計時間,只需要在 flask 的請求攔截器里面這樣寫:

  1. from flask import Flask, g, make_response, request 
  2. app = Flask(__name__) 
  3.  
  4. @app.before_request 
  5. def before_request(): 
  6.     if "profile" in request.args: 
  7.         g.profiler = Profiler() 
  8.         g.profiler.start() 
  9.  
  10.  
  11. @app.after_request 
  12. def after_request(response): 
  13.     if not hasattr(g, "profiler"): 
  14.         return response 
  15.     g.profiler.stop() 
  16.     output_html = g.profiler.output_html() 
  17.     return make_response(output_html) 

假如有這樣一個 API:

  1. @app.route("/dosomething"
  2. def do_something(): 
  3.     import requests 
  4.     requests.get("http://google.com"
  5.     return "Google says hello!" 

為了測試這個 API 的瓶頸,我們可以在 url 上加一個參數 profile 就可以:http://127.0.0.1:5000/dosomething?profile,哪一行代碼執行比較慢,結果清晰可見:

Python性能分析工具pyinstrument快速定位最慢的代碼

分析 Django 代碼

分析 Django 代碼也非常簡單,只需要在 Django 的配置文件的 MIDDLEWARE 中添加

  1. "pyinstrument.middleware.ProfilerMiddleware"

然后就可以在 url 上加一個參數 profile 就可以:

Python性能分析工具pyinstrument快速定位最慢的代碼

如果你不希望所有人都能看到,只希望管理員可以看到,settings.py 可以添加這樣的代碼:

  1. def custom_show_pyinstrument(request): 
  2.     return request.user.is_superuser 
  3.  
  4. PYINSTRUMENT_SHOW_CALLBACK = "%s.custom_show_pyinstrument" % __name__ 

如果不想通過 url 后面加參數的方式查看性能分析,可以在 settings.py 文件中添加:

  1. PYINSTRUMENT_PROFILE_DIR = 'profiles' 

這樣,每次訪問一次 Django 接口,就會將分析結果以 html 文件形式保存在 項目目錄下的 profiles 文件夾中。

分析異步代碼

簡單的異步代碼分析:

  1. import asyncio 
  2.  
  3. from pyinstrument import Profiler 
  4.  
  5.  
  6. async def main(): 
  7.     p = Profiler() 
  8.     with p: 
  9.         print("Hello ..."
  10.         await asyncio.sleep(1) 
  11.         print("... World!"
  12.     p.print() 
  13.  
  14.  
  15. asyncio.run(main()) 

復雜一些的異步代碼分析:

  1. import asyncio 
  2. import time 
  3.  
  4. import pyinstrument 
  5.  
  6.  
  7. def do_nothing(): 
  8.     pass 
  9.  
  10.  
  11. def busy_wait(duration): 
  12.     end_time = time.time() + duration 
  13.  
  14.     while time.time() < end_time: 
  15.         do_nothing() 
  16.  
  17.  
  18. async def say(what, when, profile=False): 
  19.     if profile: 
  20.         p = pyinstrument.Profiler() 
  21.         p.start() 
  22.  
  23.     busy_wait(0.1) 
  24.     sleep_start = time.time() 
  25.     await asyncio.sleep(when
  26.     print(f"slept for {time.time() - sleep_start:.3f} seconds"
  27.     busy_wait(0.1) 
  28.  
  29.     print(what) 
  30.     if profile: 
  31.         p.stop() 
  32.         p.print(show_all=True
  33.  
  34.  
  35. loop = asyncio.get_event_loop() 
  36.  
  37. loop.create_task(say("first hello", 2, profile=True)) 
  38. loop.create_task(say("second hello", 1, profile=True)) 
  39. loop.create_task(say("third hello", 3, profile=True)) 
  40.  
  41. loop.run_forever() 
  42. loop.close() 

工作原理

Pyinstrument 每 1ms 中斷一次程序,并在該點記錄整個堆棧。它使用 C 擴展名和 PyEval_SetProfile 來做到這一點,但只每 1 毫秒讀取一次讀數。你可能覺得報告的樣本數量有點少,但別擔心,它不會降低準確性。默認間隔 1ms 是記錄堆棧幀的下限,但如果在單個函數調用中花費了很長時間,則會在該調用結束時進行記錄。如此有效地將這些樣本“打包”并在最后記錄。

Pyinstrument 是一個統計分析器,并不跟蹤,它不會跟蹤您的程序進行的每個函數調用。相反,它每 1 毫秒記錄一次調用堆棧。與其他分析器相比,統計分析器的開銷比跟蹤分析器低得多。

比如說,我想弄清楚為什么 Django 中的 Web 請求很慢。如果我使用 cProfile,我可能會得到這個:

  1. 151940 function calls (147672 primitive calls) in 1.696 seconds 
  2.  
  3.    Ordered by: cumulative time 
  4.  
  5.    ncalls  tottime  percall  cumtime  percall filename:lineno(function
  6.         1    0.000    0.000    1.696    1.696 profile:0(<code object <module> at 0x1053d6a30, file "./manage.py", line 2>) 
  7.         1    0.001    0.001    1.693    1.693 manage.py:2(<module>) 
  8.         1    0.000    0.000    1.586    1.586 __init__.py:394(execute_from_command_line) 
  9.         1    0.000    0.000    1.586    1.586 __init__.py:350(execute
  10.         1    0.000    0.000    1.142    1.142 __init__.py:254(fetch_command) 
  11.        43    0.013    0.000    1.124    0.026 __init__.py:1(<module>) 
  12.       388    0.008    0.000    1.062    0.003 re.py:226(_compile) 
  13.       158    0.005    0.000    1.048    0.007 sre_compile.py:496(compile) 
  14.         1    0.001    0.001    1.042    1.042 __init__.py:78(get_commands) 
  15.       153    0.001    0.000    1.036    0.007 re.py:188(compile) 
  16.   106/102    0.001    0.000    1.030    0.010 __init__.py:52(__getattr__) 
  17.         1    0.000    0.000    1.029    1.029 __init__.py:31(_setup) 
  18.         1    0.000    0.000    1.021    1.021 __init__.py:57(_configure_logging) 
  19.         2    0.002    0.001    1.011    0.505 log.py:1(<module>) 

看完是不是還是一臉懵逼,通常很難理解您自己的代碼如何與這些跟蹤相關聯。Pyinstrument 記錄整個堆棧,因此跟蹤昂貴的調用要容易得多。它還默認隱藏庫框架,讓您專注于影響性能的應用程序/模塊:

  1.   _     ._   __/__   _ _  _  _ _/_   Recorded: 14:53:35  Samples:  131 
  2.  /_//_/// /_\ / //_// / //_'/ //    Duration: 3.131     CPU time: 0.195 
  3. /   _/                    v3.0.0b3 
  4.  
  5. Program: examples/django_example/manage.py runserver --nothreading --noreload 
  6.  
  7. 3.131 <module>  manage.py:2 
  8. └─ 3.118 execute_from_command_line  django/core/management/__init__.py:378 
  9.       [473 frames hidden]  django, socketserver, selectors, wsgi... 
  10.          2.836 select  selectors.py:365 
  11.          0.126 _get_response  django/core/handlers/base.py:96 
  12.          └─ 0.126 hello_world  django_example/views.py:4 

最后的話

 

本文分享了 pyinstrument 的用法,有了這個性能分析神器,以后優化代碼可以節省很多時間了,這樣的效率神器很值得分享,畢竟人生苦短,能多點時間干點有意思的不香么?

原文鏈接:https://mp.weixin.qq.com/s/d_3PBrwk-s34W_RzVsJ21A

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲精品一区二区在线 | 男人天堂视频网 | 免费日韩 | 亚洲国产免费 | 一级录像免费录像在线观看 | 综合伊人久久 | 欧美在线观看一区 | av在线中文 | 黄毛片视频 | 久草新免费 | 久久综合九色综合网站 | 中文字幕视频在线观看 | 久久久久久亚洲av毛片大全 | 欧美日韩成人精品 | 亚洲精选一区二区 | 国产精品日产欧美久久久久 | 一级特黄av| 日本不卡一区二区三区 | 亚洲精品久久久久久久久久久久久 | 精品视频一区在线观看 | 在线亚洲欧美 | 亚洲精品国偷拍自产在线观看 | 国产精品一区三区 | 国产精品久久久久久吹潮 | 视频二区在线观看 | 亚洲一区二区三区在线播放 | 国产精品一二区 | 日本免费在线视频 | 香蕉久久久久久 | 日本黄色一级电影 | 欧美日韩在线免费观看 | 日韩av一区二区在线观看 | av中文在线| 日韩国产欧美视频 | av成人在线观看 | 四虎久久 | 国产精品成人在线 | 亚洲aaa| 久久久精品国产 | 日本a v网站 | 最新中文字幕 |