我一直在编写一个Python脚本来分析CSV文件。其中一些文件相当大(1-2百万条记录),而且脚本需要几个小时才能完成。
我将记录处理方式从for-in循环改为while循环,速度提升显著。以下为演示:
>>> def for_list():
... for d in data:
... bunk = d**d
...
>>> def while_list():
... while data:
... d = data.pop(0)
... bunk = d**d
...
>>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> import timeit
>>> timeit.timeit(for_list)
1.0698931217193604
>>> timeit.timeit(while_list)
0.14515399932861328
速度提升近一个数量级。我从未查看过Python的字节码,但我认为这可能会有所帮助,但事实证明while_list
拥有更多的指令。
那么这里发生了什么?我能够将其应用于其他程序吗?在哪些情况下for
比while
快十倍?
编辑:正如@HappyLeapSecond指出的那样,我没有完全理解timeit
内部正在发生的情况,使用以下代码后差异消失了:
>>> def for_list():
... data = [x for x in range(1000)]
... for d in data:
... bunk = d**d
...
>>> def while_list():
... data = [x for x in range(1000)]
... while data:
... d = data.pop(0)
... bunk = d**d
>>> timeit.timeit(while_list, number=1000)
12.006330966949463
>>> timeit.timeit(for_list, number=1000)
11.847280025482178
很奇怪的是,我的“真正”脚本在做出如此简单的更改后加速了这么多。我最好的猜测是迭代方法需要更多的交换?我有一个40G的交换分区,该脚本占用其中约15-20G。弹出会减少交换吗?
for
循环创建一个迭代器可能相对昂贵。尝试让你的列表变得更长,例如100k条目,并进行比较。 - 9000