日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Python利用memory_profiler實(shí)現(xiàn)內(nèi)存分析_python

作者:Sir?老王 ? 更新時(shí)間: 2022-11-25 編程語(yǔ)言

任何編程語(yǔ)言開發(fā)的項(xiàng)目代碼都是需要考慮內(nèi)存問題的,有時(shí)候當(dāng)項(xiàng)目體量比較龐大以后若是出現(xiàn)內(nèi)存泄漏等問題分析起來更是哦力不從心的。

因此,平時(shí)建議從開發(fā)的每個(gè)函數(shù)入手盡量編寫的標(biāo)準(zhǔn)、規(guī)范,不至于造成后期無法修復(fù)的BUG,這個(gè)python非標(biāo)準(zhǔn)模塊memory_profiler值得一看。

使用memory_profiler能分析出每行代碼塊的內(nèi)存資源使用情況,有兩種方式可以參考,一種是開發(fā)完代碼塊通過命令行的方式執(zhí)行即可。

另一種則在直接代碼塊時(shí)直接生成內(nèi)r內(nèi)存資源情況的日志可以隨時(shí)查看。

使用python pip的方式安裝memory_profiler非標(biāo)準(zhǔn)庫(kù),默認(rèn)使用清華大學(xué)的python鏡像站。

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

開發(fā)一個(gè)函數(shù)func_while,其中運(yùn)行一個(gè)100萬次的循環(huán)并且在循環(huán)中打印每一次循環(huán)執(zhí)行時(shí)的時(shí)間戳,將內(nèi)存使用情況保存到日志文件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("開始循環(huán)應(yīng)用:{0}".format(begin))

????n?=?0

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

????end?=?timeit.default_timer()
????logger.info("結(jié)束循環(huán)應(yīng)用:{0}".format(end))

????logger.info('循環(huán)應(yīng)用總共用時(shí):{0}'.format(str(end?-?begin)))

func_while()

# 2022-09-17 22:18:18.767 | INFO ????|?__main__:func_while:39 -?當(dāng)前時(shí)間戳:1397.349649192
# 2022-09-17 22:18:18.769 | INFO ????|?__main__:func_while:39 -?當(dāng)前時(shí)間戳:1397.350927206
# 2022-09-17 22:18:18.770?| INFO ????|?__main__:func_while:39 -?當(dāng)前時(shí)間戳:1397.352256128
# 2022-09-17 22:18:18.771 | INFO ????|?__main__:func_while:39 -?當(dāng)前時(shí)間戳:1397.353639651
# 2022-09-17 22:18:18.773 | INFO ????|?__main__:func_while:39 -?當(dāng)前時(shí)間戳:1397.354919308
# 2022-09-17 22:18:18.774 | INFO ????|?__main__:func_while:43 -?結(jié)束循環(huán)應(yīng)用:1397.35619568
# 2022-09-17 22:18:18.775 | INFO ????|?__main__:func_while:45 -?循環(huán)應(yīng)用總共用時(shí):1394.6941001149999

從上面的運(yùn)行時(shí)間可以看出整個(gè)100萬次的循環(huán)整整跑了23分鐘才完成,本身電腦性能不是很好為了測(cè)試差點(diǎn)就宕機(jī)了。下面是memory.log內(nèi)存分析的文件中的部分截圖。

從結(jié)果可以發(fā)現(xiàn)在我的while循環(huán)這一行下面的代碼塊整個(gè)內(nèi)存顯示-65303MB左右,可以看出整個(gè)內(nèi)存消耗出現(xiàn)非常大的問題,怪不得的應(yīng)用的主線程直接就卡死了。

在上面的分析中,我們選用的內(nèi)存統(tǒng)計(jì)的精度是保留四位小數(shù),也就是@profile注解的precision屬性值的設(shè)置是4。

接下來使用第二種方式,也就是直接運(yùn)行查看效果,或者在命令行執(zhí)行.py的python文件效果是一樣的都會(huì)展示出內(nèi)存的消耗情況,但是這種情況可能會(huì)出現(xiàn)內(nèi)存精度缺失的情況。

為了保險(xiǎn)起見,這次我還是直接選用1萬次循環(huán)來進(jìn)行測(cè)試查看效果,循環(huán)次數(shù)過多怕把我的操作機(jī)直接搞崩潰了!

@profile(precision=4)
def?func_while2():
????"""
????It?prints?the?numbers?from?0?to?9999.
????"""
????begin?=?timeit.default_timer()
????logger.info("開始循環(huán)應(yīng)用:{0}".format(begin))

????n?=?0

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

????end?=?timeit.default_timer()
????logger.info("結(jié)束循環(huán)應(yīng)用:{0}".format(end))

????logger.info('循環(huán)應(yīng)用總共用時(shí):{0}'.format(str(end?-?begin)))


func_while2()

# 2022-09-17 22:37:38.086 | INFO ????|?__main__:func_while2:81 -?當(dāng)前時(shí)間戳:15.020861643
# 2022-09-17 22:37:38.087 | INFO ????|?__main__:func_while2:85 -?結(jié)束循環(huán)應(yīng)用:15.022343696
# 2022-09-17 22:37:38.089 | INFO ????|?__main__:func_while2:87 -?循環(huán)應(yīng)用總共用時(shí):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("開始循環(huán)應(yīng)用:{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('當(dāng)前時(shí)間戳:{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("結(jié)束循環(huán)應(yīng)用:{0}".format(end))
#?????86
#???? 87  29.8125 MiB ??0.0000 MiB ????????? 1 ????? logger.info('循環(huán)應(yīng)用總共用時(shí):{0}'.format(str(end - begin)))

顯然執(zhí)行1萬次循環(huán)結(jié)果算是正常的,增量只有0.0703 MiB,只用了13秒就執(zhí)行完成了,可能使用for循環(huán)的話效果還要好一些。

原文鏈接:https://mp.weixin.qq.com/s/meUGrnKBso1G5cVyWEboGQ

欄目分類
最近更新