【问题标题】:Python performance gains when destructing instances within a for loop在 for 循环中破坏实例时 Python 性能提升
【发布时间】:2019-03-21 21:11:48
【问题描述】:

我正在使用 Python 脚本读取一些 ASCII 文件,操作它们的值并获得输出。计算是在类实例化中完成的,类似于伪形式

def __init__(input)
  self.input = input
  self.output = function of input 

伪代码,在问号之间有争议的部分,是

open file
read lines
for each lines in file: 
    split line
    construct class instance with input from split-line values
    store instance.output in a help variable (list)
    ?? delete class instance ??
further processing of the help variable
etc

删除类实例是节省时间和内存的障碍还是机会?问题的规模很大(不足 100 万行)。

我很清楚我宁愿从二进制文件中读取,但目前这不可行。另外,我选择类构造是因为优雅,也许随着脚本的发展,我可以从封装中获得更多好处。但是,如果有人建议这样做,我可以在这个阶段放弃它。

【问题讨论】:

  • 根据我对python中垃圾收集器的了解,一旦一个对象变得无法访问,它就会被垃圾收集——如果你用相同的引用重新定义构造的类,你就无法到达初始对象并且它会被垃圾收集反正

标签: python performance loops class destructor


【解决方案1】:

为什么要编写伪代码,而不仅仅是 python?无论如何,在 python 中,如果您只想在下一个循环中使用新实例覆盖名称,那么删除类实例是没有意义的。当没有为它持有引用时,解释器将自动删除内存中的对象。

所以这两个选项花费的时间几乎相同(见下文):

from collections import UserList

def with_del():
    for i in range(10000):
        x = UserList([i])
        del x

def without_del():
    for i in range(10000):
        x = UserList([i])

%timeit with_del()
8.19 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit without_del()
8.04 ms ± 92.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

with_del 可能需要稍长的时间,因为要运行额外的字节码指令。

【讨论】:

  • 感谢您的回答。为什么要编写伪代码,而不仅仅是 python?只是匆忙离开我的源代码。
【解决方案2】:

当作为垃圾收集过程的一部分不再引用实例时,Python 会自动为您销毁实例,因此您不应自己执行此操作,除非您确实希望在仍有引用时删除该实例。

在您的情况下,每次迭代都会创建新实例,并且由于您仅将源自实例的输出而不是实例本身存储到列表中,因此您不会保留对旧实例的任何引用下一次迭代,因此垃圾收集过程将以有效的方式为您销毁实例,因此您不必担心自己做。自己做实际上会更慢,因为您将使用 Python 代码进行删除,而不是使用纯粹在 C 中实现的垃圾收集。

【讨论】:

    猜你喜欢
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多