为什么 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
的定义会
运行 cell
或 code
一次。
我读过这个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
.
问题:
- 为什么有 2 种不同的方法来 运行 使用
-n<N>
来 code_block
和
-r<R>
?
-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中,可以看到n
和r
是如何影响计时过程的:
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
我正在尝试 运行 在 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
的定义会
运行 cell
或 code
一次。
我读过这个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
.
问题:
- 为什么有 2 种不同的方法来 运行 使用
-n<N>
来code_block
和-r<R>
? -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中,可以看到n
和r
是如何影响计时过程的:
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