我需要将大量的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
我跑了几次,第二种方法的速度一直是第一种方法的两倍。为什么差异如此之大?
答案 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)
这实际上是您的特定计算机硬件的问题,可能与pipelining和ALU详细信息有关,以及这些循环实际上是如何本地执行的,所以我无法回答明确。但我的猜测是,在这个特定的代码块中,乘法,除法和模数都需要大致相同的时间量,并且该时间大于加或减。因此,在示例1中有两个较慢的操作,但在示例2中只有一个。
编辑:正如在他的回答中表示的那样,这可能是一个分裂与其他操作的问题。但同样,如果没有更多细节,就不可能肯定地说出来。