我有一个大文件,我正在读取,并将每几行转换为一个对象的实例.
由于我循环遍历文件,因此我使用list.append(instance)将实例存储到列表中,然后继续循环.
这是一个约100MB左右的文件,因此它不会太大,但随着列表变大,循环逐渐减慢.(我打印循环中每圈的时间).
这不是循环所固有的〜当我循环浏览文件时打印每个新实例时,程序以恒定速度进行〜只有当我将它们附加到列表时才会变慢.
我的朋友建议在while循环之前禁用垃圾收集,然后启用它并进行垃圾收集调用.
有没有其他人观察到list.append变慢的类似问题?有没有其他方法来规避这个?
我将尝试以下两个建议.
(1)"预先分配"记忆〜这样做的最佳方法是什么?(2)尝试使用deque
多个帖子(请参阅Alex Martelli的评论)建议内存碎片化(他有像我这样的大量可用内存)〜但没有明显的性能修复.
要复制这种现象,请运行下面答案中提供的测试代码,并假设这些列表包含有用的数据.
gc.disable()和gc.enable()有助于计时.我还会仔细分析所有时间花在哪里.
我编写了一段代码,其中列表大小随着每次迭代而增加,迭代次数可以达到近100000次.
样品:
def do_something():
Lst.append(k)
while N < 100000:
if k not in Lst:
do_something()
Run Code Online (Sandbox Code Playgroud)
现在,我注意到这种方法需要很长时间才能完成.请注意,我确实设置了setrecursionlimit().事实上令人尴尬的是,该计划一直在运行.
之后,在尝试寻找优化代码的方法时,我将Lst转换为Dct.所以代码看起来像:
def do_something():
Dct[k] = True
while N < 100000:
if Dct[k] == False:
do_something()
Run Code Online (Sandbox Code Playgroud)
代码运行得更快.在阅读了几个关于SOF的对话(重复附加到大型列表(Python 2.6.6))后,我意识到它的列表不是很慢,而是如何处理更大的列表数据的内存.这个网站https://wiki.python.org/moin/TimeComplexity,揭示了列表和dict查找时间的复杂性.列表中的O(n),其中Dct查找为O(1).这是Dct表现更好的原因吗?如何执行列表查找和Dict查找?