2014-11-06 45 views
7

我隨機選擇了這些數字,但這些結果看起來是一致的 - 浮點型指數比整型指數快25%-50%。這些處理有何不同?整數指數爲什麼numpy.power更慢?

In [209]: %timeit -n 100000 -r 100 np.power(3.71242, 7) 
100000 loops, best of 100: 3.45 µs per loop 

In [210]: %timeit -n 100000 -r 100 np.power(3.71242, 7.0) 
100000 loops, best of 100: 1.98 µs per loop 
+0

如果我不得不冒險猜測,numpy需要一個浮點數,但收到一個int並需要轉換。 – 2014-11-06 03:10:51

+0

@JeffMercado有趣的想法---但它似乎不太合起來:「%timeit -n 100000 -r 10 if(type(2)== int):float(2)」 ==>「100000循環,最好10:每個循環571 ns「 – DilithiumMatrix 2014-11-06 03:15:30

+0

我懷疑int指數會導致實際乘法,而浮點型指數會導致使用日誌。 – 2014-11-06 03:28:49

回答

13

np.poweruniversal function(ufunc)。這些函數可用於具有各種不同數據類型的標量和數組,但必須首先檢查輸入值的類型,以便他們可以確定使用哪個內部循環來生成合適的輸出值。

如果輸入類型不映射到任何ufunc的預定義循環,則ufunc將嘗試cast the input values to suitable types(除非另有說明)。輸入值的檢查和轉換具有與其相關的性能成本,從而解釋了問題中觀察到的時間。

ufunc的types屬性顯示輸入數據類型將如何映射到輸出數據類型。下面是映射爲np.power名單:

>>> np.power.types # 'input input -> output' 
['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 
'QQ->Q', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'OO->O'] 

浮點數屬於字符代碼'g',Python的整數屬於'l'。這些字符代碼的完整列表可以在here找到。

請注意,對於此ufunc,兩個輸入值的數據類型必須相同。例如,對於floatint輸入數據類型的混合沒有映射。

但我們仍然可以給np.power不同的數據類型,並讓它將值轉換爲適當的數據類型。對於floatint,返回float64號:

>>> np.power(3.71242, 7).dtype 
dtype('float64') 

在上面,你可以看到,它映射到float64字符代碼g唯一的輸入是另外兩個g值:'gg->g'

所以,在幕後,np.power(3.71242, 7)了一個Python float和一個Python int,不得不決定它可以安全地重鑄到什麼類型。 int值被安全地提升爲float型g。 ufunc然後知道要運行哪個循環,並返回另一個值g

由於這個原因,不混合輸入數據類型導致np.power更好的性能。