djh*_*ese 10 python numpy cython
我一直在玩Cython以准备其他工作.我尝试了一个简单的测试用例,并注意到我的代码执行更大问题大小的方式有些奇怪.我创建了一个简单的最小/最大函数,用于计算2D float32数组的最小值和最大值,并将其与运行进行比较numpy.min(a), numpy.max(a).对于10000个元素的数组,性能类似.对于1000000个元素的数组,cython表现得更糟.这是我的cython代码:
import numpy
cimport cython
cimport numpy
DTYPE = numpy.float32
ctypedef numpy.float32_t DTYPE_t
@cython.boundscheck(False)
@cython.wraparound(False)
def minmax_float32(numpy.ndarray[DTYPE_t, ndim=2] arr):
cdef DTYPE_t min = arr[0, 0]
cdef DTYPE_t max = arr[0, 0]
cdef int row_max = arr.shape[0]
cdef int col_max = arr.shape[1]
cdef int x, y
for y in range(row_max):
for x in range(col_max):
if arr[y, x] < min:
min = arr[y, x]
if arr[y, x] > max:
max = arr[y, x]
return min, max
Run Code Online (Sandbox Code Playgroud)
这是我在ipython中完成的简单时间:
a = numpy.random.random(10000).reshape((100, 100)).astype(numpy.float32)
%timeit -r3 -n50 (numpy.min(a), numpy.max(a))
# 50 loops, best of 3: 22.2 µs per loop
%timeit -r3 -n50 minmax_float32(a)
# 50 loops, best of 3: 23.8 µs per loop
a = numpy.random.random(1000000).reshape((1000, 1000)).astype(numpy.float32)
%timeit -r3 -n50 (numpy.min(a), numpy.max(a))
# 50 loops, best of 3: 307 µs per loop
%timeit -r3 -n50 minmax_float32(a)
# 50 loops, best of 3: 1.22 ms per loop
307 / 22.2
# 13.82882882882883
1220 / 23.8
# 51.26050420168067
Run Code Online (Sandbox Code Playgroud)
有没有人知道为什么cython需要更长时间才能获得更大的输入?这只是我正在玩的东西,但如果你有任何提示或技巧我有兴趣听到它们.提前致谢.
编辑:我在带有8GB内存的macbook 10.10上运行这些测试.用macports中的gcc编译cython,并在他们的教程中提到了标志-shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing.
看起来 NumPy 在min和可用的情况下使用 SSE 指令max,这意味着它们可能比 Cython 更大程度地利用您的硬件。
以下是SSE 中NumPymin和归约实现的源代码:https: //github.com/numpy/numpy/blob/master/numpy/core/src/umath/simd.inc.src#L696。请注意,他们使用预处理器同时自动生成多种数据类型和操作的代码。max