我需要將大量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
我跑了好幾次和第二個方法是始終圍繞兩倍的速度第一個。爲什麼差異如此之大?
我需要將大量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
我跑了好幾次和第二個方法是始終圍繞兩倍的速度第一個。爲什麼差異如此之大?
>>> 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
在第二種情況下,模運算簡單地優化掉。
哈哈,不錯:)我認爲一個聰明的編譯器會優化整個表達式,無論它如何寫... – Michael
@Vasiliy:巴掌,前額 – LetMeSOThat4U
在現實生活中,我認爲127的值會作爲變量而不是常量傳入,在這種情況下,m2中的優化消失。 – jwygralak67
這實際上是一個關於您的特定計算機硬件的問題,可能與pipelining和ALU的詳細信息有關,以及這些循環如何實際在本機執行,因此我無法明確回答。但我的猜測是,在這個特定的代碼塊中,乘法,除法和模數都需要大致相同的時間,並且該時間大於加法或減法。所以你在示例1中有兩個較慢的操作,但在示例2中只有一個。
編輯:正如在他的答案中顯示的那樣,它可能是一個與其他操作相比的問題。但是,再次,不可能說沒有更多的細節。
司是相對於根據以下timeit結果的其它操作(+
,-
,*
,%
)繁重的操作:
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
UPDATE
我錯了。 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
更好地使用變量,因爲編譯器*可能會優化文字操作。 –
@TimPeters,感謝您的評論。我更新了包含變量版本的答案。 – falsetru
@falsetru:儘管如此,有一個= 127,p = 60和運行'%timeit a - a%p' vs'%timeit(a/p)* p'。所以蒂姆是對的,你是對的。 :-) – LetMeSOThat4U
該分區比乘法,減法和模運算要昂貴得多。 –
哪個版本的Python?我想知道這裏'/'是整數除法還是浮點除法。 –
@TimPeters如果兩個參數都是整數,則/是整數除法。 –