首頁 > 軟體

Python利用memory_profiler實現記憶體分析

2022-10-18 14:01:24

任何程式語言開發的專案程式碼都是需要考慮記憶體問題的,有時候當專案體量比較龐大以後若是出現記憶體漏失等問題分析起來更是哦力不從心的。

因此,平時建議從開發的每個函數入手儘量編寫的標準、規範,不至於造成後期無法修復的BUG,這個python非標準模組memory_profiler值得一看。

使用memory_profiler能分析出每行程式碼塊的記憶體資源使用情況,有兩種方式可以參考,一種是開發完程式碼塊通過命令列的方式執行即可。

另一種則在直接程式碼塊時直接生成內r記憶體資源情況的紀錄檔可以隨時檢視。

使用python pip的方式安裝memory_profiler非標準庫,預設使用清華大學的python映象站。

pip install memory_profiler -i https://pypi.tuna.tsinghua.edu.cn/simple/

開發一個函數func_while,其中執行一個100萬次的迴圈並且在迴圈中列印每一次迴圈執行時的時間戳,將記憶體使用情況儲存到紀錄檔檔案memory.log中。

# Importing the timeit module.
import timeit

# A logging library.
from loguru import logger

# A decorator that will wrap the function and add some code to it.
from memory_profiler import profile


@profile(precision=4, stream=open("memory.log", "w+"))
def func_while():
    """
    It prints the numbers from 0 to 999999.
    """
    begin = timeit.default_timer()
    logger.info("開始迴圈應用:{0}".format(begin))

    n = 0

    while n < 1000000:
        logger.info('當前時間戳:{0}'.format(timeit.default_timer()))
        n = n + 1

    end = timeit.default_timer()
    logger.info("結束迴圈應用:{0}".format(end))

    logger.info('迴圈應用總共用時:{0}'.format(str(end - begin)))

func_while()

# 2022-09-17 22:18:18.767 | INFO     | __main__:func_while:39 - 當前時間戳:1397.349649192
# 2022-09-17 22:18:18.769 | INFO     | __main__:func_while:39 - 當前時間戳:1397.350927206
# 2022-09-17 22:18:18.770 | INFO     | __main__:func_while:39 - 當前時間戳:1397.352256128
# 2022-09-17 22:18:18.771 | INFO     | __main__:func_while:39 - 當前時間戳:1397.353639651
# 2022-09-17 22:18:18.773 | INFO     | __main__:func_while:39 - 當前時間戳:1397.354919308
# 2022-09-17 22:18:18.774 | INFO     | __main__:func_while:43 - 結束迴圈應用:1397.35619568
# 2022-09-17 22:18:18.775 | INFO     | __main__:func_while:45 - 迴圈應用總共用時:1394.6941001149999

從上面的執行時間可以看出整個100萬次的迴圈整整跑了23分鐘才完成,本身電腦效能不是很好為了測試差點就宕機了。下面是memory.log記憶體分析的檔案中的部分截圖。

從結果可以發現在我的while迴圈這一行下面的程式碼塊整個記憶體顯示-65303MB左右,可以看出整個記憶體消耗出現非常大的問題,怪不得的應用的主執行緒直接就卡死了。

在上面的分析中,我們選用的記憶體統計的精度是保留四位小數,也就是@profile註解的precision屬性值的設定是4。

接下來使用第二種方式,也就是直接執行檢視效果,或者在命令列執行.py的python檔案效果是一樣的都會展示出記憶體的消耗情況,但是這種情況可能會出現記憶體精度缺失的情況。

為了保險起見,這次我還是直接選用1萬次迴圈來進行測試檢視效果,迴圈次數過多怕把我的操作機直接搞崩潰了!

@profile(precision=4)
def func_while2():
    """
    It prints the numbers from 0 to 9999.
    """
    begin = timeit.default_timer()
    logger.info("開始迴圈應用:{0}".format(begin))

    n = 0

    while n < 10000:
        logger.info('當前時間戳:{0}'.format(timeit.default_timer()))
        n = n + 1

    end = timeit.default_timer()
    logger.info("結束迴圈應用:{0}".format(end))

    logger.info('迴圈應用總共用時:{0}'.format(str(end - begin)))


func_while2()

# 2022-09-17 22:37:38.086 | INFO     | __main__:func_while2:81 - 當前時間戳:15.020861643
# 2022-09-17 22:37:38.087 | INFO     | __main__:func_while2:85 - 結束迴圈應用:15.022343696
# 2022-09-17 22:37:38.089 | INFO     | __main__:func_while2:87 - 迴圈應用總共用時:12.908313867
# Filename: C:/the-public/the-public/test013/test7.py
#
# Line #    Mem usage    Increment  Occurrences   Line Contents
# =============================================================
#     73  29.7266 MiB  29.7266 MiB           1   @profile(precision=4)
#     74                                         def func_while2():
#     75  29.7266 MiB   0.0000 MiB           1       begin = timeit.default_timer()
#     76  29.7422 MiB   0.0156 MiB           1       logger.info("開始迴圈應用:{0}".format(begin))
#     77
#     78  29.7422 MiB   0.0000 MiB           1       n = 0
#     79
#     80  29.8125 MiB   0.0000 MiB       10001       while n < 10000:
#     81  29.8125 MiB   0.0703 MiB       10000           logger.info('當前時間戳:{0}'.format(timeit.default_timer()))
#     82  29.8125 MiB   0.0000 MiB       10000           n = n + 1
#     83
#     84  29.8125 MiB   0.0000 MiB           1       end = timeit.default_timer()
#     85  29.8125 MiB   0.0000 MiB           1       logger.info("結束迴圈應用:{0}".format(end))
#     86
#     87  29.8125 MiB   0.0000 MiB           1       logger.info('迴圈應用總共用時:{0}'.format(str(end - begin)))

顯然執行1萬次迴圈結果算是正常的,增量只有0.0703 MiB,只用了13秒就執行完成了,可能使用for迴圈的話效果還要好一些。

到此這篇關於Python利用memory_profiler實現記憶體分析的兩種方法總結的文章就介紹到這了,更多相關Python memory_profiler記憶體分析內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com