【发布时间】:2018-01-24 02:41:33
【问题描述】:
我试图了解如何最好地利用 numpy 数组的 C 排序来编写高性能代码。我的期望是遍历行的操作应该比遍历列的操作更快。事实上,我尝试的第一个例子就是这样:
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
这是我的预期,因为沿行求和应该比沿列求和更快。
这是我非常困惑的地方。如果我将 dtype 更改为 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
有人能解释一下为什么会这样吗?
编辑:在 cmets 中建议我使用较小的矩阵 (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。
-
尝试减小
X(即(1000,1000))的大小,看看时差是否在某个点从~200% 跳到~110%。您可能正在缓存。 -
转载于 Win7/32B,
python 3.5.2和numpy 1.11.1 -
实际上,我认为您必须使数组更大,至少在您正在操作的维度上,才能始终如一地看到差异。
标签: python numpy row-major-order