为什么计算这么大的时差呢?

时间:2013-12-17 16:31:13

标签: python

我需要将大量的UNIX时间戳分解为各自的分钟(再次表示为时间戳)。

出于纯粹的好奇心,我计时两种方法:

%timeit (127/60)*60
10000000 loops, best of 3: 76.2 ns per loop

%timeit 127 - 127%60
10000000 loops, best of 3: 34.1 ns per loop

我跑了几次,第二种方法的速度一直是第一种方法的两倍。为什么差异如此之大?

3 个答案:

答案 0 :(得分:8)

>>> import dis
>>> method1 = lambda: (127 / 60) * 60
>>> method2 = lambda: 127 - 127 % 60
>>> dis.dis(method1)
  1           0 LOAD_CONST               1 (127)
              3 LOAD_CONST               2 (60)
              6 BINARY_DIVIDE       
              7 LOAD_CONST               2 (60)
             10 BINARY_MULTIPLY     
             11 RETURN_VALUE        
>>> dis.dis(method2)
  1           0 LOAD_CONST               1 (127)
              3 LOAD_CONST               3 (7)
              6 BINARY_SUBTRACT     
              7 RETURN_VALUE        

在第二种情况下,模数运算只是被优化掉了。

答案 1 :(得分:3)

根据以下时间结果,分部相对于其他操作(+-*%)是繁重的操作:

In [9]: timeit 127 + 12
100000000 loops, best of 3: 14.8 ns per loop

In [10]: timeit 127 - 12
100000000 loops, best of 3: 14.8 ns per loop

In [11]: timeit 127 * 12
100000000 loops, best of 3: 14.9 ns per loop

In [12]: timeit 127 / 12
10000000 loops, best of 3: 40 ns per loop

In [13]: timeit 127 % 12
100000000 loops, best of 3: 14.7 ns per loop

<强>更新

我错了。正如Tim Peters评论的那样,使用变量,显示出不同的结果。

In [1]: a, b = 127, 12

In [2]: timeit a + b
10000000 loops, best of 3: 37.6 ns per loop

In [3]: timeit a - b
10000000 loops, best of 3: 37.9 ns per loop

In [4]: timeit a * b
10000000 loops, best of 3: 52.7 ns per loop

In [5]: timeit a / b
10000000 loops, best of 3: 54 ns per loop

In [6]: timeit a % b
10000000 loops, best of 3: 56.5 ns per loop

答案 2 :(得分:2)

这实际上是您的特定计算机硬件的问题,可能与pipeliningALU详细信息有关,以及这些循环实际上是如何本地执行的,所以我无法回答明确。但我的猜测是,在这个特定的代码块中,乘法,除法和模数都需要大致相同的时间量,并且该时间大于加或减。因此,在示例1中有两个较慢的操作,但在示例2中只有一个。

编辑:正如在他的回答中表示的那样,这可能是一个分裂与其他操作的问题。但同样,如果没有更多细节,就不可能肯定地说出来。