(三) python性能分析-line_profiler模塊(時間)、memory_profiler模塊(空間)

前言

??在進行模型測試過程中,我們通常需要知道整個預測過程所消耗的時間與空間,以及哪個部分存在瓶頸,才能進行后續的優化。因此,本文介紹我常用的性能分析工具--line_profilermemory_profiler

一、時間分析--line_profiler模塊

1.1 安裝

$ pip3 install line_profiler

1.2 用法

??line_profiler使用裝飾器(@profile)標記需要調試的函數。用kernprof運行代碼,被選函數每一行花費的cpu時間以及其他信息就會被記錄下來。

# demo.py
@profile
def foo():
    task = []
    for a in range(0, 101):
        for b in range(0, 101):
            if a + b == 100:
                task.append((a, b))
    return task
 
@profile
def run():
    for item in foo():
        pass
 
if __name__ == '__main__':
    run()

運行下面的命令

kernprof -l -v demo.py

-l表示逐行分析,-v用于輸出。
同時會輸出一個文件:demo.py.lprof,后期可以對.lprof文件進行分析輸出結果。

python -m line_profiler demo.py.lprof

1.3 結果分析

Wrote profile results to demo.py.lprof
Timer unit: 1e-06 s

Total time: 0.004891 s
File: demo.py
Function: foo at line 1

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     1                                           @profile
     2                                           def foo():
     3         1          0.0      0.0      0.0      task = []
     4       102         23.0      0.2      0.5      for a in range(0, 101):
     5     10302       2260.0      0.2     46.2          for b in range(0, 101):
     6     10201       2578.0      0.3     52.7              if a + b == 100:
     7       101         30.0      0.3      0.6                  task.append((a, b))
     8         1          0.0      0.0      0.0      return task

Total time: 0.008603 s
File: demo.py
Function: run at line 11

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    11                                           @profile
    12                                           def run():
    13       102       8584.0     84.2     99.8      for item in foo():
    14       101         19.0      0.2      0.2          pass

Timer unit: 1e-06 s:時間單位;
Total time: 0.004891 s:總時間;
Hit:代碼運行次數;
%Time:代碼占了它所在函數的消耗的時間百分比,通常直接看這一列。

二、內存分析--memory_profiler模塊

2.1 安裝

??首先安裝memory_profiler和psutil(psutil主要用于提高memory_profile的性能,建議安裝)(可使用pip直接安裝)

$ pip install memory_profiler
$ pip install psutil

2.2 用法

(1) ?1.在函數前添加 @profile
? ? 2.運行方式: python -m memory_profiler test.py
? ? 此方法缺點:在調試和實際項目運行時 要增刪 @profile 此裝飾器

(2) ?1.先導入:from memory_profiler import profile
? ? 2.函數前加裝飾器: @profile(precision=4, stream=open('memory_profiler.log','w+'))
? ?? ?? ?? ?? ? 參數含義:precision:精確到小數點后幾位 ;
? ?? ?? ?? ?? ? stream:此模塊分析結果保存到 'memory_profiler.log' 日志文件。如果沒有此參 數,分析結果會在控制臺輸出;
? ?運行方式:直接跑此腳本 python memory_profiler_test.py ;
? ?此方法優點:解決第一種方法的缺點,在不需要分析時,直接注釋掉此行。

(3)

腳本代碼和方法二一樣,但是運行方式不同:
mprof run memory_profiler_test.py   : 分析結果會保存到一個 .dat格式文件中
mprof plot                          : 把結果以圖片到方式顯示出來(直接在本目錄下運行此命令即可,程序會自動找出.dat文件) (要安裝  pip install matplotlib)
mprof clean                         : 清空所有 .dat文件

2.3 結果分析

Filename: demo.py

Line #    Mem usage    Increment   Line Contents
================================================
     1   49.160 MiB   49.160 MiB   @profile
     2                             def foo():
     3   49.160 MiB    0.000 MiB       task = []
     4   49.160 MiB    0.000 MiB       for a in range(0, 101):
     5   49.160 MiB    0.000 MiB           for b in range(0, 101):
     6   49.160 MiB    0.000 MiB               if a + b == 100:
     7   49.160 MiB    0.000 MiB                   task.append((a, b))
     8   49.160 MiB    0.000 MiB       return task


Filename: demo.py

Line #    Mem usage    Increment   Line Contents
================================================
    11   49.160 MiB   49.160 MiB   @profile
    12                             def run():
    13   49.160 MiB   49.160 MiB       for item in foo():
    14   49.160 MiB    0.000 MiB           pass

Mem usage : 運行內存大小;
Increment : 運行當前代碼后,增加的內存。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。