Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python在垃圾收集上花费了过多的时间_Python_Pandas_Garbage Collection_Performance Testing - Fatal编程技术网

Python在垃圾收集上花费了过多的时间

Python在垃圾收集上花费了过多的时间,python,pandas,garbage-collection,performance-testing,Python,Pandas,Garbage Collection,Performance Testing,我正在处理一段复杂的python代码,它将大约40%的执行时间用于垃圾收集 ncalls tottime percall cumtime percall filename:lineno(function) **6028 494.097 0.082 494.097 0.082** {built-in method gc.collect} 1900 205.709 0.108 205.709 0.108 {built-in method time

我正在处理一段复杂的python代码,它将大约40%的执行时间用于垃圾收集

 ncalls    tottime  percall  cumtime  percall filename:lineno(function)

 **6028  494.097    0.082  494.097    0.082** {built-in method gc.collect}

 1900  205.709    0.108  205.709    0.108 {built-in method time.sleep}

  778   26.858    0.035  383.476    0.493 func1.py:51(fill_trades)

有没有办法减少对gc.collect的调用数量?我尝试了gc.disable(),但它的有效性受到限制,因为Cpython主要使用引用计数。我正在使用python 3.6

如果没有看到代码,就不可能正确回答。不过,您可以使用一些通用技巧来改善这种情况

主要的一点是:限制分配的数量。您是否经常在小包装中重新包装一些无用的值?你经常复制字符串的一部分吗?您是否在执行大量复制数据的消息解析?找出最常分配内存的内容并加以改进。这可能会有帮助

针对具体情况的修复:

  • 你做了很多数学密集型的运算吗?也许移动到类似于
    numpy
    的东西会有所帮助,因为您可以使用真实的、可变的、类型化的数组而不是列表
  • 你有很多数据处理代码吗?您可以使用
    cython
    对其上的类型进行注释并编译模块,以消除将值包装到python对象中的需要
  • 对于原始内存(解析/文件处理/…),您可以使用
    memoryview
    s保存一些分配:
最后,你确定收集时间有问题吗?从跟踪中,您可以看到列表中的第二位是
time.sleep
。如果您的
gc.collect
占用运行时间的40%,那么
time.sleep
占用16%——为什么不在此时触发收集呢?不管怎样,你还是在睡觉

编辑:另外,我确信你在某处明确地调用了
gc.collect
。呼叫不会自动出现在
pstats
输出上。要查找位置,请尝试:

your_pstats_object.print_callers('gc.collect')

我遇到了类似的问题,我的代码90%的时间都花在垃圾收集上。在测试中,我的函数每次调用大约需要90毫秒,但在生产中,每次调用大约需要1秒。我通过CopyWarning查看了pandas的
设置的安静形式

在我的例子中,我创建了一个数据帧的切片,如
df=pd.dataframe(data)[fieldlist]
,然后分配了一个新列
df['foo']=…
。此时,
df.\u is\u copy
显示我们对原始数据帧有一个weakref,因此当我们调用它时,它会执行一个完整的垃圾收集周期来杀死weakref


在生产环境中,我的代码试图每秒调用该函数几次,缓存中有大量大型对象(dict),因此垃圾收集周期非常昂贵。首先确保我没有创建副本,性能几乎提高了15倍,从而修复了此问题:-

您能发布一些代码吗?很难说为什么你的代码会频繁地触发垃圾收集而没有看到它,或者是一个与你的真实代码非常相似的可复制的示例。我不是手动调用gc.collect。这是pstats的输出。代码太大,无法在此处发布。代码严重依赖对象。如果有人能够在没有看到任何代码的情况下回答这个问题,我会感到惊讶。带a的问题更有可能得到答案。尤其是像这样复杂的事情,“严重依赖对象”。这就是垃圾收集器工作如此努力的原因。谢谢你的建议。谢谢你的建议。pandas调用了gc.collect()。经过一些搜索,我发现pd.set_选项('mode.chained_assignment',None)可以禁用pandas中对gc.collect的显式调用