我想了解如何最好地利用numpy數組的C順序來編寫高性能代碼。我的期望是,遍歷行的操作應該比遍歷列的操作更快。事實上,這是真的,因爲我嘗試的第一個例子:dtype如何影響Numpy中的行和列操作速度?
X = np.ones((10000,10000),dtype='int64')
print(X.dtype)
print(X.flags)
%timeit np.sum(X,axis=0)
%timeit np.sum(X,axis=1)
這將產生輸出:
int64
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
10 loops, best of 3: 79.6 ms per loop
10 loops, best of 3: 61.1 ms per loop
這是我所期待的,因爲沿行總結應該比沿着列求和更快。
這裏是我非常困惑的地方。如果我改變了D型到float64,則列操作變得幾乎快兩倍行操作:
X = np.ones((10000,10000),dtype='float')
print(X.dtype)
print(X.flags)
%timeit np.sum(X,axis=0)
%timeit np.sum(X,axis=1)
生成輸出:
float64
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
10 loops, best of 3: 67.7 ms per loop
10 loops, best of 3: 123 ms per loop
是否有人可以解釋,爲什麼發生這種情況?
編輯:在評論中建議我再試一次較小的矩陣(1000,1000)。當我運行:
import time
import numpy as np
X = np.ones((1000,1000),dtype='float')
print(X.dtype)
print(X.flags)
%timeit np.sum(X,axis=0)
%timeit np.sum(X,axis=1)
X = np.ones((1000,1000),dtype='int64')
print(X.dtype)
print(X.flags)
%timeit np.sum(X,axis=0)
%timeit np.sum(X,axis=1)
我得到的輸出:
float64
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
1000 loops, best of 3: 598 µs per loop
1000 loops, best of 3: 1.06 ms per loop
int64
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
1000 loops, best of 3: 788 µs per loop
1000 loops, best of 3: 632 µs per loop
所以效果持久。
你有什麼'numpy'和'python'版本? –
@DanielF Python 3.6,Numpy 1.11.3。 – jmracek
嘗試減小'X'的大小(即'(1000,1000)'),並查看在某個時間點的時間差是否從〜200%跳到〜110%。你可能會緩存。 –