定期删除长字典/列表是Python的好习惯



我一直在写一个很长的脚本,偶尔构建大的字典和/或列表,我想知道当我完成使用它们时,是否可以通过使用del删除它们来提高性能。或者把这些对象留在周围,让垃圾收集来处理是正常的做法吗?这里的最佳实践是什么?谢谢。

del不等于free(3)。它不会强制Python释放内存。它最终可能根本不会释放内存。您应该避免将它与内存使用完全联系在一起。

del所做的唯一事情是从其作用域中删除名称。(或从集合中删除项,或删除属性。但我猜你说的不是这个。

有效:

del foo

等价于:

del LOCAL_SCOPE['foo']

所以这不会释放任何内存:

massive_list = list(range(1000000))
same_massive_list = massive_list
del massive_list

…因为它所做的只是删除名称 massive_list。底层对象仍然有另一个名称same_massive_list,因此它不会消失。del不是用于控制Python内存管理的秘密钩子;这只是请求 Python调用其内存管理的几种方法之一。

(顺便说一下,CPython是重新计数+循环收集,而不是垃圾收集。对象在最后一个引用消失后立即释放。垃圾不会躺在那里等着被清理。当然,其他实现做不同的事情;例如,PyPy是垃圾收集。)

现在,如果您使用的名称是列表/字典/其他的名称,那么del肯定会使其refcount降为零,因此它将被释放。但是,因为del的语义实际上是关于删除名称,所以我不会在这种情况下使用它。我只是让变量退出作用域(如果可行的话),或者将名称重新分配给空白列表,或None,或任何对您的程序有意义的名称。您甚至可以就地清空列表,即使同一列表有多个名称也可以使用:

foo = list(range(1000000))
bar = foo
foo[:] = []
# Both `bar` and `foo` still refer to the original list, but now it's empty

您可以使用d.clear()对字典执行相同的操作。

我在名字上使用del的唯一地方是在类或模块作用域中,我暂时需要一些帮助值,但真的真的不想将其暴露为API的一部分。这真的很少见,但这是我遇到的唯一情况,我实际上想要"删除这个名称"的语义。

del通常是不必要的。

在CPython中,对象在没有引用时消失。del只删除一个对象引用;如果还有其他对象的引用,它将留在周围,并且del实际上没有做任何事情来改善您的内存状况。

相反,简单地将变量重新赋值给一个不同的对象(例如,在循环的顶部创建一个新的空列表),也将最终减少对该对象的引用,隐式地执行与del相同的操作。如果此时没有其他对该对象的引用,它将立即被释放。

还要记住,局部变量在函数返回时消失,所以您不需要显式地del您在函数中定义的任何名称。

一个例外是循环引用,其中两个(或多个)对象相互引用,但实际上没有一个对象可以通过名称访问;Python会周期性地对这些对象进行垃圾收集,但如果在处理完对象后打破循环,则可以更快地释放它们。(这可能只需要一个del !)不过,这种情况可能非常罕见。

在ironpython(运行在。net CLR上)或Jython(运行在JVM上)中,最佳内存管理策略可能不同,因为使用了底层VM的垃圾收集器。

Python的优点之一(与C等语言相比)是,通常您不必担心内存管理的细节,您可以专注于程序的目的。

所以我的建议是不要打扰,除非你有理由这样做(例如,python正在吃掉你所有的RAM)。

相关内容

  • 没有找到相关文章

最新更新