在课堂上,我经常使用Python模块timeit
来比较代码片段的执行时间。例如,在IPython下:
def test1(a, b):
if a > b:
(a, b) = (b, a)
return (a,b)
def test2(a, b):
(a, b) = (min(a, b), max(a,b))
return (a,b)
%timeit test1(5, 6); test1(6, 5)
%timeit test2(5, 6); test2(6, 5)
输出(YMMV):
584 ns ± 31.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
1.96 µs ± 212 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
以下输出可以使比较更容易:
5.84e-7 s ± 3.10e-8 s per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
1.96e-6 s ± 2.12e-7 s per loop (mean ± std. dev. of 7 runs, 100000 loops each)
从Python 3.5开始,命令行API中有一个选项--unit
,它接受sec
作为值。但是测量多行语句很麻烦。我无法看到如何在Python API中使用相同的参数,更不用说在IPython下了。
我很感激任何建议。
编辑:根据Matt的回答,%timeit -o
将其结果作为TimeitResult
返回,它拥有我感兴趣的属性。因此,可能的解决方法是:
timeit_result1 = %timeit -oq test1(5, 6); test1(6, 5)
print("{:.2e} sec".format(timeit_result1.best))
timeit_result2 = %timeit -oq test2(5, 6); test2(6, 5)
print("{:.2e} sec".format(timeit_result2.best))
输出:
5.34e-07 sec
1.71e-06 sec
注意:中间分配似乎是强制性的。 AFAIK,%timeit -o...
不是正常表达。
答案 0 :(得分:1)
如果使用%timeit -o
选项,则可以分配结果(TimeitResult
对象),提取相关字段,自行格式化字符串,或在图表中使用。这包括在循环中使用%timeit
,这对于查找函数的时间复杂度非常有用(使用{variable}
来传递参数)。如果需要,时间格式代码ipython在IPython/core/magics/execution.py
中使用here。
IPython没有强制特定单位的选项(尽管它可以让你加入它)。不要写自己的魔法(正如你在评论中所建议的那样),请为IPython本身提出补丁,我们很乐意引导您完成整个过程并进行审核。