python的`timeit`并不总是与数字成线性比例?

时间:2016-09-27 18:37:25

标签: python performance optimization timeit

我在16GB,2.7GHz i5,OSX 10.11.5机器上运行Python 2.7.10。

我在许多不同类型的例子中多次观察到这种现象,所以下面的例子虽然有点人为但具有代表性。这正是我今天早些时候正在努力的事情,当我的好奇心终于被激起时。

>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100)
3.790855407714844e-05
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000)
0.0003371238708496094
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=10000)
0.014712810516357422
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=100000)
0.029777050018310547
>>> timeit('unicodedata.category(chr)', setup = 'import unicodedata, random; chr=unichr(random.randint(0,50000))', number=1000000)
0.21139287948608398

你会注意到,从100到1000,正如预期的那样,时间增加了10倍。然而,1e3到1e4,它更像是因子50,然后是从1e4到1e5的因子2(所以从1e3到1e5的总因数为100,这是预期的)。

我认为必须在定时的实际过程中或在timeit本身中进行某种基于缓存的优化,但我无法凭经验弄清楚是否是这种情况。进口似乎并不重要,可以通过一个最基本的例子来观察:

>>> timeit('1==1', number=10000)
0.0005490779876708984
>>> timeit('1==1', number=100000)
0.01579904556274414
>>> timeit('1==1', number=1000000)
0.04653501510620117

从1e4到1e6,存在1e2时间差的真实因子,但中间步长为~30和~3。

我可以做更多的临时数据收集,但此时我还没有想到一个假设。

关于为什么在某些中间数的运行中出现非线性标度的任何概念?

1 个答案:

答案 0 :(得分:8)

这与较少数量的运行不够准确,无法获得所需的时序分辨率。

当您增加运行次数时,时间之间的比率接近运行次数之间的比率:

                    countActivity       
                maxDaily    meanDaily
userID  weekday     
3       0       84066       18275.6
        1       78208       20698.5
        2       172579      64930.75
        3       89535       25443
        4       6152        2809