Python利用memory_profiler实现内存分析
作者:Sir 发布时间:2022-10-02 12:41:45
任何编程语言开发的项目代码都是需要考虑内存问题的,有时候当项目体量比较庞大以后若是出现内存泄漏等问题分析起来更是哦力不从心的。
因此,平时建议从开发的每个函数入手尽量编写的标准、规范,不至于造成后期无法修复的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
猜你喜欢
- 看下面的一组例子:alert(true.toString());alert(false.toString());alert(1.123.to
- 卷积函数python提供了多种卷积方案,相比之下,定义在ndimage中的卷积函数,在功能上比numpy和signal中的卷积要稍微复杂一些
- 最近使用工作需要,使用了Navicat8.2版本,发现备份数据都是默认存储在C盘,这个就比较郁闷了。重做系统忘记转移了。那不就死定了?找了一
- 现在我们用python代码实现感知器算法。# -*- coding: utf-8 -*-import numpy as npclass Pe
- Oracle9i中提供强大的迁移功能,可以从多种数据库向Oracle迁移数据。Oracle新发行的迁移工具提供了从Access2
- 项目中要对短文本进行相似度估计,word2vec是一个很火的工具。本文就word2vec的训练以及加载进行了总结。word2vec的原理就不
- 数据库配置1.安装数据库:自行安装 我的SQL Server版本为2019 2.登录数
- var str='1250' ; alert( Number(str) ); //得到1250 alert(parseInt
- 本文实例讲述了Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法。分享给大家供大家参考,具体如下:1. 定义类python
- 很久没有跟其他人做重构思想方面的交流了,可能大家都觉得不太好意思讨论,特别是“分离”的思想这么基础的话题,拿出来说怕会被“笑话”。做为页面重
- 一、python线程的模块1.1 thread和threading模块thread模块提供了基本的线程和锁的支持threading提供了更高
- 使用背景逛社区发现许多人在解决删除文件夹中非图片文件,删除文件夹中图片等问题的时候,都写了很多代码取实现这一功能,我当时就纳闷了,能几行代码
- Python 中要将单个项目列表转换为整数:访问索引 0 处的列表。将结果分配给变量。该变量将存储列表中的唯一项目。my_list = [2
- *****看一下我定义的change()和run()函数******绘图坐标体系:作用:设置主窗体的大小和位置turtle.setup(wi
- datetime 和 smalldatetime 代表日期和一天内的时间的日期和时间数据类型。 Microsoft SQL Server 用
- 问题描述:将python脚本设置成开机自启。环境:windows7 64位前段时间,一直想把文件打包成exe文件,然后设置成开机自启,虽然感
- Python 异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作。注意,和 else 语句不同,f
- declare @Table_name varchar(60) set @Table_name = 'Pay_inputpay
- 什么是爬虫爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源
- 代码实现如下:import win32com.client,os,timedef word_encryption(path, passwor