例如我有一个列表:
L=[-13, -24, -21, -3, -23, -15, -14, -27, -13, -12]
如果输入
%timeit -n 10 myList = [item for item in L if item < 15]输出为10 loops, best of 3: 1.25 µs per loop如果我输入
myGen = (item for item in L if item < 15)输出为1000000 loops, best of 3: 561 ns per loop
我不明白情况 2,为什么生成器需要 1000000 次循环而不是 10 次循环? “best of 3”是什么意思?我如何计算出每个 commond 所需的总秒数,例如情况 1 的 10*1.25=12.5 us?
请您参考如下方法:
您没有包含 -n %timeit 的参数在你的第二个例子中,ipython 根据试运行需要多长时间来改变重复次数;被测试的代码段越快,迭代次数越多,以获得更准确的每次迭代时间值。
此外,测试会运行多次以尽量减少外部因素(例如,当您的操作系统恰好安排了磁盘缓冲区刷新,而其他一切都变得有点慢)。这就是“三者之最”的用武之地;测试连续运行 3 次,并选择了最佳时机。
参见 %timeit magic command documentation ,其中包括这些选项及其默认行为:
-n<N>: execute the given statement<N>times in a loop. If this value is not given, a fitting value is chosen.
-r<R>: repeat the loop iteration<R>times and take the best result. Default: 3
您的第一个示例确实使用-n 10所以它只运行了 10 次。
因为用生成器表达式创建一个 generator 对象几乎是即时的,ipython 可以比执行列表理解更频繁地执行循环方式(它必须执行 for 循环并生成一个列出所有结果的对象然后)。请记住,在您驱动迭代之前,生成器表达式不会执行任何工作。
如果您想比较生成器表达式产生与列表理解相同的结果所需的时间,您必须实际迭代。您可以将表达式传递给 list()也调用实际生成列表:
%timeit -n 10 myGen = (item for item in L if item < 15); list(myGen)
这会更慢,因为生成器的开销比列表理解多一点:
In [1]: L=[-13, -24, -21, -3, -23, -15, -14, -27, -13, -12]
In [2]: %timeit -n 10 myList = [item for item in L if item < 15]
10 loops, best of 3: 1.29 µs per loop
In [3]: %timeit -n 10 myGen = (item for item in L if item < 15); list(myGen)
10 loops, best of 3: 1.72 µs per loop
请注意,您必须在每次测试迭代时重新创建生成器,因为生成器只能产生一次输出。
