以10的幂而不是SI前缀输出经过的时间

时间:2017-12-07 09:54:53

标签: python-3.x ipython scientific-notation timeit

在课堂上,我经常使用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... 不是正常表达。

1 个答案:

答案 0 :(得分:1)

如果使用%timeit -o选项,则可以分配结果(TimeitResult对象),提取相关字段,自行格式化字符串,或在图表中使用。这包括在循环中使用%timeit,这对于查找函数的时间复杂度非常有用(使用{variable}来传递参数)。如果需要,时间格式代码ipython在IPython/core/magics/execution.py中使用here

IPython没有强制特定单位的选项(尽管它可以让你加入它)。不要写自己的魔法(正如你在评论中所建议的那样),请为IPython本身提出补丁,我们很乐意引导您完成整个过程并进行审核。