python的性能優化方案

python的性能優化方案

python的GIL,多線程,多進程

  • GIL: Global Interpreter Lock(全局解釋器鎖),每個CPU在同一時間之內只能執行一個線程,因爲單核CPU的多線程其實都只是併發不是並行。
  • 單CPU中進程只能是併發,多CPU進程可以並行
  • 單CPU單核中線程只能併發,單CPU多核中線程可以並行
  • 並行: 多事件在同一時刻發生
  • 併發: 多事件在同一時間間隔內發生
  • 每個線程的執行方式: 獲取GIL --> 執行代碼 --> 釋放GIL,在一個python進程裏面,只有一個GIL,如果線程拿不到這個GIL就無法運行。
  • GIL的釋放邏輯: 1. python2:當前線程遇見IO操作或者ticks計數達到100。2. python3:改用計時器,執行時間達到閥值釋放GIL


使用Ubuntu Apache AB進行壓力測試

sudo apt-get install apache2-utils
ab -n 100 -c 10 http://localhost/demo/
-n 代表的是總的請求數,-c代表一次併發裏面的請求數


具體項目優化方案:

  1. read DB:讀取數據庫的時候,使用cache

  2. 代碼邏輯:儘量避免在for循環裏面使用query

  3. 給logger加上判斷,當debug模式爲False的時候,很多不必要的地方不需要寫log

  4. gunicorn:使用gevent啓用worker,將worker的數量變成三個,核數+1,將gevent放在requirement中。Worker個數,Worker類型,TImeout時間

  5. Nginx: 修改配置文件,timeout設置爲600/300s
    在最外面加上:

    worker_rlimit_nofile 65535;
    

    在http塊內加上:

    fastcgi_send_timeout 600;
    fastcgi_read_timeout 600;
    

    在server塊的location裏面加上:

    proxy_connect_timeout 600s;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    
  6. NAS:掛載參數上需要增加一個noresvport參數來規避以後例行維護可能造成的NAS服務中斷https://c.tb.cn/a.cAQOl

  7. 使用python的一些計算運行時間的工具來優化代碼,CProfile、line_profiler、TimeDelta

  8. 對python本身的一些優化 pypy/cpython



使用line_profiler工具分析python代碼性能以及性能調優

line_profiler是一個對函數進行逐行分析的模塊,kernprof是一個可以運行line_profiler或者python標準庫cProfile的一個很方便的腳本工具。

安裝:
$ pip install line_profiler
遇到錯誤提示沒有Cpython,安裝一下:
pip install Cpython
繼續報錯:command 'x86_64-linux-gnu-gcc' failed with exit status 1
解決方案:https://github.com/scrapy/scrapy/issues/2115 裏面的sudo apt install python3.6-dev解決了問題

首先使用kernprof腳本運行來開始我們的性能優化工作:

kernprof -l run.py

上面的操作會創建一個LineProfiler的實例並且會把它插入到命名空間裏面。然後它能以裝飾器的方式來使用,所以我們只需要把我們需要分析的函數上面套上這個裝飾器:

@profile
def func_need_profile(*args, **kwargs):
	...

這裏直接加上裝飾器,不需要在代碼裏面額外import任何東西。

kernprof會把分析的結果放在script_to_profile.py.lprof這個二進制文件裏面,然後我們可以去看這個分析結果:

python -m line_profiler run.py.lprof
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章