Python新手笔记:plt.clf()与内存泄漏——为什么我的循环越跑越慢?

写此文的目的:警醒我自己。。。因为一个plt.clf()的问题卡壳了一整天

问题描述:用python写了一个for循环把序列数据批量转换成图片,然后在for循环里写了如下几句

def get_image(scaled_data,start,number):#scaled_data:传入的数组 start:起始下标 len:待处理的数据量
    column = scaled_data.shape[1]  # 传入数组的列数=格拉姆角场大小
    counter=start
    for i in scaled_data[start:start+number]:#遍历待处理部分 生成格拉姆角场并保存图片
        arccos_X = np.arccos(i)  # 求反余弦
        field = [a+b for a in arccos_X for b in arccos_X]
        gram = np.cos(field).reshape(-1,column)#格拉姆角场
        plt.axis('off')  # 关闭坐标
        plt.imshow(gram)
        plt.savefig('GAF_Image/train_in_'+str(counter)+'.png',bbox_inches='tight',pad_inches = 0)#保存图片
        print("\r",end="")
        print("generating No."+str(counter+1)+"/"+str(start+number),end="")
        counter += 1  # 图片序号+1
    print("generated all pictures successfully!")

乍一看好像没什么问题,跑起来也没报错,但是有个问题就是,随着时间推移,图片的生成速度会越来越慢,开始一秒三张,一分钟过后变成了一秒一张,5分钟过后就变成10秒一张了。。。

检查了一个晚上,排查结果如下:

循环调用print语句会延长代码的运行时间

python的for循环效率太低,得想办法加速

针对以上问题,开展了各种挽救措施,然鹅卵用没有,因为这些问题根本就不是关键!

关键就是题目里的plt.clf(),官方的解释如下:

嗯,很简短,还是说说我的个人理解吧,figure就是图形,clear the current figure就是清除当前的图形,此外还会保留当前的窗口以便下次绘图,具体解释可以参考【matplotlib】 之 清理、清除 axes 和 figure (plt.cla、plt.clf、plt.close)_tz_zs的博客-CSDN博客

如果在循环绘图过程中不使用plt.clf()就会造成内存泄漏(应该是这个意思),之前用于绘图的内存无法被释放掉,导致后面的图形堆叠在前面的图形上,如果打开生成的图片,可能会看到一堆重叠的线条之类的,可惜因为特殊原因,我把重叠的图当成正常的图了。。。

在运行时间上的体现就是,循环会越跑越慢,越跑越慢,知道屏幕前的你没有耐心,直至崩溃

所以,及时释放内存真的很重要,之前生成图片忽略了这一点,吃了大亏,下面放上修改后的代码,出图速度很稳定,基本可以一秒出好几张

def get_image(scaled_data,start,number):#scaled_data:传入的数组 start:起始下标 len:待处理的数据量
    column = scaled_data.shape[1]  # 传入数组的列数=格拉姆角场大小
    counter=start
    for i in scaled_data[start:start+number]:#遍历待处理部分 生成格拉姆角场并保存图片
        arccos_X = np.arccos(i)  # 求反余弦
        field = [a+b for a in arccos_X for b in arccos_X]
        gram = np.cos(field).reshape(-1,column)#格拉姆角场
        plt.axis('off')  # 关闭坐标
        plt.imshow(gram)
        plt.savefig('GAF_Image/train_in_'+str(counter)+'.png',bbox_inches='tight',pad_inches = 0)#保存图片
        print("\r",end="")
        print("generating No."+str(counter+1)+"/"+str(start+number),end="")
        plt.clf()#手动清理 防止内存泄漏
        counter += 1  # 图片序号+1
    print("generated all pictures successfully!")

总结:用plt画完图或者保存完图片后立刻打上plt.clf()等清除语句,防止内存泄漏,节省debug时间 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值