精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-03
最后修改:2011-05-03
起因前段时间,在做文本处理的实验时,需要预加载大量的原始数据(100W),在Python中使用的字典(dict)类型负责保存这些数据,很快就开发完成 了一个Demo版,然而程序执行的效率不是那么令人满意,通过使用Python中的profile发现,影响程序执行性能的关键语句就那么几条(用 dict保存加载后原始数据,这是个循环遍历。) 解决问题既然找到了问题源,于是就勒起衣袖开始动手尝试使用各种解决方案替代效率不佳的,经过多次的反复尝试,调优的效果不太明显,最后一个idea:考虑Python垃圾回收机制的影响了,最后也证明了这个想法的靠谱程度,本文后续部分将分享调优的过程与测试结果。 浅谈Python垃圾回收机制
在使用C语言开发时代,我们的开发效率(生产力的问题)受牵制于内存释放、泄露等问题,于是普遍的口号---“指针好难学”。时过境迁,当今的流行的语言都配套了内存自动回收机制,从而使我们有更多的精力去纠结于业务上处理。 调优之前为了便于描叙如前文所述的加载大量原始数据的问题,使用了虚假的数据,这部分程序片段完成的功能倒没有发生变化,以下是调优之前的程序片段: data = range(1,5000000) wdict = dict(zip(data,data)) 使用time python test.py运行,我们可以看到以下结果(机器的差异,显示的结果也将不同): real 0m39.066s user 0m26.422s sys 0m12.313s 如果使用linux下的top命令,您将动态的看到内存的使用情况,该程序运行后将缓慢的吞噬内存,由于程序运行时的内存对象都是有效的,因此垃圾回收触 发时,无法释放这部分内存,而垃圾回收程序却在做无用功(达到threshold阀值),显而易见,程序的执行性能将大打折扣。那么我们的调优手段也就很 容易了,在程序片段运行的这段时间内禁止进行垃圾回收。 调优之后以下是调优之后的程序片段(禁止程序片段的垃圾回收): import gc gc.disable() data = range(1,5000000) wdict = dict(zip(data,data)) gc.enable() 使用time python test.py运行,我们可以看到以下结果(机器的差异,显示的结果也将不同): real 0m2.760s user 0m1.208s sys 0m1.532s 通过上面的运行结果对比,显而易见,调优后的程序性能明显大幅提升,如果使用Linux下的top命令,您将动态的看到内存的使用情况也是不同的,该程序运行后迅速的吞噬内存,对比调优之前的程序片段,减少了垃圾回收的频频触发。 总结通过这次的调优体验,发现Python垃圾回收频频触发将会影响程序执行的性能,因此,正如很多同学所说,Python程序的执行速度慢是不是有垃圾回收机制的一份功劳呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-05-03
写的很清楚 如果禁止垃圾回收 是否要考虑堆栈溢出的情况?会不会出现在禁止垃圾回收的这一段语句运行期,占用完了本进程所申请的堆栈内存?python会自动扩充默认堆栈内存吗?
|
|
返回顶楼 | |
发表时间:2011-05-11
congdepeng 写道 写的很清楚 如果禁止垃圾回收 是否要考虑堆栈溢出的情况?会不会出现在禁止垃圾回收的这一段语句运行期,占用完了本进程所申请的堆栈内存?python会自动扩充默认堆栈内存吗?
写得不错,这个确实要考虑 |
|
返回顶楼 | |
发表时间:2011-05-13
感谢分享,现在的机器内存很大的说,用空间换时间应该很划算 :-)
|
|
返回顶楼 | |
发表时间:2011-05-14
最后修改:2011-05-14
congdepeng 写道 写的很清楚 如果禁止垃圾回收 是否要考虑堆栈溢出的情况?会不会出现在禁止垃圾回收的这一段语句运行期,占用完了本进程所申请的堆栈内存?python会自动扩充默认堆栈内存吗?
在Python中一切都是对象,除了类型对象是静态初始化,其余的对象都是在堆上分配内存,因此不会出现您说的堆栈溢出。这种方案是空间换时间。 |
|
返回顶楼 | |
浏览 8448 次