網站首頁 編程語言 正文
任何編程語言開發的項目代碼都是需要考慮內存問題的,有時候當項目體量比較龐大以后若是出現內存泄漏等問題分析起來更是哦力不從心的。
因此,平時建議從開發的每個函數入手盡量編寫的標準、規范,不至于造成后期無法修復的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循環的話效果還要好一些。
原文鏈接:https://mp.weixin.qq.com/s/meUGrnKBso1G5cVyWEboGQ
相關推薦
- 2022-05-12 Kotlin map 高級函數返回新的集合
- 2022-09-22 nodeSelector:Pod 定向調度
- 2023-01-02 Python利用socket實現多進程的端口掃描器_python
- 2022-04-08 Swift使用表格組件實現單列表_Swift
- 2023-01-07 基于Go語言實現選擇排序算法及優化_Golang
- 2022-08-21 Caffe圖像數據轉換成可運行leveldb?lmdb文件_其它綜合
- 2022-05-10 Install fail Error: Unsupported URL Type “workspac
- 2022-04-08 Android統一依賴管理的三種方式總結_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支