为什么垃圾回收如此缓慢?

8

使用IPython的%prun对我的代码进行性能分析,我发现大部分函数时间都花费在垃圾回收上(0.334秒 vs. 0.428秒总时间)。

79254 function calls (77408 primitive calls) in 0.428 seconds

Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     5    0.334    0.067    0.334    0.067 {gc.collect}
 15757    0.005    0.000    0.007    0.000 {isinstance}
  1584    0.002    0.000    0.004    0.000 dtypes.py:68(is_dtype)

我尝试在调用函数之前和返回值后禁用/启用垃圾回收,但时机几乎相同。

import gc

gc.disable()
x = foo()
gc.disable()

有人知道为什么这是一个瓶颈,以及如何加速吗?

我的Python/Pandas版本如下:

Python 2.7.11 |Continuum Analytics, Inc.| (default, Dec  6 2015, 18:57:58) 
Pandas 0.17.1

4
我想你的代码会产生很多垃圾。 - Klaus D.
1
我猜答案是“不行”,但你能在这里分享任何代码吗?否则,也许你可以写一些演示这个垃圾回收问题的东西。:s - Andy Hayden
@AndyHayden 我还在进行性能分析。看起来瓶颈是运行大量回归的函数。如果我可以组合一个最小可重现示例,我会编辑我的帖子。 - Alexander
1
另一个想法是覆盖 gc.collect = lambda: None (然后再放回去!)。也许有些更深层次的东西启用了 gc 并手动进行收集。不知道这是否真正有效,但值得一试。 - Andy Hayden
1
@stefan 不,这已经不是我的优先事项了。如果有任何进展,我可能很快会重新考虑这个问题,并给出更新。 - Alexander
显示剩余3条评论
2个回答

1

嘿,只有慢的在GC部分说“TODO:以某种方式找出他的意思”。 - kilojoules

0

您禁用了gc,因此可能实际上有某些东西在显式地调用gc.collect。您可以在IPython中使用以下技巧来找到罪魁祸首:

import gc
import traceback

old_collect = gc.collect

def new_collect(*args, **kwargs):
    traceback.print_stack()
    old_collect(*args, **kwargs)

gc.collect = new_collect

请注意,此代码仅适用于使用import gc导入gc模块的情况,不适用于使用from gc import collect的情况(因为我们正在操作gc模块)。

如果您发现任何问题,请报告错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接