2013-12-17 32 views
4

我需要將大量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

該分區比乘法,減法和模運算要昂貴得多。 –

+1

哪個版本的Python?我想知道這裏'/'是整數除法還是浮點除法。 –

+0

@TimPeters如果兩個參數都是整數,則/是整數除法。 –

回答

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   

在第二種情況下,模運算簡單地優化掉。

+0

哈哈,不錯:)我認爲一個聰明的編譯器會優化整個表達式,無論它如何寫... – Michael

+0

@Vasiliy:巴掌,前額 – LetMeSOThat4U

+0

在現實生活中,我認爲127的值會作爲變量而不是常量傳入,在這種情況下,m2中的優化消失。 – jwygralak67

2

這實際上是一個關於您的特定計算機硬件的問題,可能與pipeliningALU的詳細信息有關,以及這些循環如何實際在本機執行,因此我無法明確回答。但我的猜測是,在這個特定的代碼塊中,乘法,除法和模數都需要大致相同的時間,並且該時間大於加法或減法。所以你在示例1中有兩個較慢的操作,但在示例2中只有一個。

編輯:正如在他的答案中顯示的那樣,它可能是一個與其他操作相比的問題。但是,再次,不可能說沒有更多的細節。

3

司是相對於根據以下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 
+2

更好地使用變量,因爲編譯器*可能會優化文字操作。 –

+0

@TimPeters,感謝您的評論。我更新了包含變量版本的答案。 – falsetru

+0

@falsetru:儘管如此,有一個= 127,p = 60和運行'%timeit a - a%p' vs'%timeit(a/p)* p'。所以蒂姆是對的,你是對的。 :-) – LetMeSOThat4U