为什么 ipython 魔术函数 `%timeit -n1 code_block` 会多次执行 `code_block`?

Why does the ipython magic function `%timeit -n1 code_block` execute `code_block` multiple times?

我正在尝试 运行 在 ipython 中多次使用特定测试 %timeit 神奇的功能。出于演示目的,我将只使用 -n1 而不是 -n3 这里,并使用一个简单的 print(1) 函数。

%%timeit%timeit 帮助说明如下:

Options: -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 (the 3 here is a typo in ipython, for which I have submitted a
PR)

但是,如果我执行以下操作:

%%timeit -n1
print(1)

%timeit -n1 print(1)

它实际上连续打印了1 7次如下

In[1]: %timeit -n1 print(1)
1
1
1
1
1
1
1
32.8 µs ± 38.7 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

我原以为 %%timeit/%timeit 的定义会 运行 cellcode 一次。

我读过这个post: 其中给出了一些示例 %%timeit 运行s 和 ipython 魔术函数 %%timeit 的实际源代码 这里:https://github.com/ipython/ipython/blob/ec3d1a11bf26a0962cb2cf55ba263b12ac023183/IPython/core/magics/execution.py#L944

他们定义了两种类型的循环:1) -n<N> 和 2) -r<R>

如果我只用了-n1,好像也假设我用了-r7,即 -n1 默认为 -n1 -r7。这意味着即使我想让它 运行 恰好 1 运行,它仍然会 运行 code_block 7 次 https://github.com/ipython/ipython/blob/ec3d1a11bf26a0962cb2cf55ba263b12ac023183/IPython/core/magics/execution.py#L1021 除非我还指定 -n1 -r1.

问题:

  1. 为什么有 2 种不同的方法来 运行 使用 -n<N>code_block-r<R>?
  2. -n<N>-r<R> 有什么区别,为什么会这样 有必要吗?

这些参数也在timeit module.

  • -n 确定您 运行 函数(或块,或其他) 计时 window 中的次数。于是秒表开始,代码是运行n次,然后秒表结束。您应该 运行 它足够多次,结果才有意义(timeit 默认为 10 的幂,直到 0.2 秒过去)。
  • -r 确定您应该重复多少次(其中重复为 "start timer, run n times, stop timer")。由于您 CPU 调度其他进程等原因,总会出现一些错误,因此通常您需要 运行 几次,然后取这些 r 次中的最佳值。 (timeit 默认为 3,源代码中的注释 link 表明 ipython 做同样的事情——但实际代码可能不同意)。

在伪python中,可以看到nr是如何影响计时过程的:

time_hist = []
for _ in range(r):
    t0 = time.now()              # Start stopwatch (.now() is not a real function)
    for _ in range(n):
        # <your code block>
    t1 = time.now()              # Stop stopwatch

    time_hist.append(t1 - t0)    # Append time delta

 return min(time_hist)           # Return the min of the r deltas