Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python cython Memory查看速度比预期慢_Python_Numpy_Cython_Memoryview - Fatal编程技术网

Python cython Memory查看速度比预期慢

Python cython Memory查看速度比预期慢,python,numpy,cython,memoryview,Python,Numpy,Cython,Memoryview,我已经开始使用cython中的MemoryView来访问numpy阵列。它们的一个优点是比旧的numpy缓冲区支持快得多: 然而,我有一个例子,旧的numpy缓冲区支持比memoryView更快! 这怎么可能?!我想知道我是否正确使用了MemoryView 这是我的测试: import numpy as np cimport numpy as np cimport cython @cython.boundscheck(False) @cython.wraparound(False) cpde

我已经开始使用cython中的MemoryView来访问numpy阵列。它们的一个优点是比旧的numpy缓冲区支持快得多:

然而,我有一个例子,旧的numpy缓冲区支持比memoryView更快! 这怎么可能?!我想知道我是否正确使用了MemoryView

这是我的测试:

import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef np.ndarray[np.uint8_t, ndim=2] image_box1(np.ndarray[np.uint8_t, ndim=2] im, 
                                               np.ndarray[np.float64_t, ndim=1] pd,  
                                               int box_half_size):
    cdef unsigned int p0 = <int>(pd[0] + 0.5)  
    cdef unsigned int p1 = <int>(pd[1] + 0.5)    
    cdef unsigned int top = p1 - box_half_size
    cdef unsigned int left = p0 - box_half_size
    cdef unsigned int bottom = p1 + box_half_size
    cdef unsigned int right = p0 + box_half_size    
    cdef np.ndarray[np.uint8_t, ndim=2] box = im[top:bottom, left:right] 
    return box 

@cython.boundscheck(False)
@cython.wraparound(False)
cpdef np.uint8_t[:, ::1] image_box2(np.uint8_t[:, ::1] im, 
                                    np.float64_t[:] pd,  
                                    int box_half_size):

    cdef unsigned int p0 = <int>(pd[0] + 0.5)  
    cdef unsigned int p1 = <int>(pd[1] + 0.5)    
    cdef unsigned int top = p1 - box_half_size
    cdef unsigned int left = p0 - box_half_size
    cdef unsigned int bottom = p1 + box_half_size
    cdef unsigned int right = p0 + box_half_size     
    cdef np.uint8_t[:, ::1] box = im[top:bottom, left:right]   
    return box 
将numpy导入为np
cimport numpy作为np
西姆波特赛顿酒店
@cython.boundscheck(错误)
@cython.wrapparound(假)
cpdef np.ndarray[np.uint8_t,ndim=2]图像框1(np.ndarray[np.uint8_t,ndim=2]im,
np.ndarray[np.float64_t,ndim=1]pd,
整数框(半个大小):
cdef无符号整数p0=(pd[0]+0.5)
cdef无符号整数p1=(pd[1]+0.5)
cdef unsigned int top=p1-方框大小
cdef unsigned int left=p0-框大小
cdef unsigned int bottom=p1+方框大小的一半
cdef unsigned int right=p0+方框大小
cdef np.ndarray[np.uint8_t,ndim=2]框=im[顶部:底部,左侧:右侧]
返回框
@cython.boundscheck(错误)
@cython.wrapparound(假)
cpdef np.uint8_t[:,::1]图像框2(np.uint8_t[:,::1]im,
np.64_t[:]pd,
整数框(半个大小):
cdef无符号整数p0=(pd[0]+0.5)
cdef无符号整数p1=(pd[1]+0.5)
cdef unsigned int top=p1-方框大小
cdef unsigned int left=p0-框大小
cdef unsigned int bottom=p1+方框大小的一半
cdef unsigned int right=p0+方框大小
cdef np.uint8_t[:,::1]框=im[上:下,左:右]
返回框
计时结果如下:

图像_框1:键入的numpy: 100000个回路,最好3个:每个回路11.2 us

图2:内存视图: 100000个回路,最好的3个:每个回路18.1 us


这些测量是在IPython上使用%timeit image_box1(im、pd、box_一半大小)

好的!我发现了问题。 正如seberg指出的,memoryview的速度似乎较慢,因为测量包括从numpy数组到memoryview的自动转换

我使用以下函数从cython模块中测量时间:

def test(params):   
    import timeit
    im = params[0]
    pd = params[1]
    box_half_size = params[2]
    t1 = timeit.Timer(lambda: image_box1(im, pd, box_half_size))
    print 'image_box1: typed numpy:'
    print min(t1.repeat(3, 10))
    cdef np.uint8_t[:, ::1] im2 = im
    cdef np.float64_t[:] pd2 = pd
    t2 = timeit.Timer(lambda: image_box2(im2, pd2, box_half_size))
    print 'image_box2: memoryview:'
    print min(t2.repeat(3, 10)) 
结果:

图像_框1:键入的numpy: 9.07607864065e-05

图2:内存视图: 5.81799904467e-05

所以记忆视图确实更快

请注意,在调用image_box2之前,我将im和pd转换为MemoryView。如果我不执行此步骤,直接传递im和pd,则image_box2会变慢:

图像_框1:键入的numpy: 9.12262257771e-05

图2:内存视图:
0.000185245087778

我想您是在用python对这些函数计时?从那时起,返回值也是第二个函数中的一个
np.ndarray
(我假设),这可能已经解释了速度减慢的原因,因为制作
np.ndarray
是一项额外的工作,总体上没有太多的工作要做。是的,我从IPython使用命令:%timeit image\u box1(im,pd,box\u半个大小)我刚刚编辑了我的问题,将cython中的计时功能包括在内。记忆视图仍然比较慢!校正你说得对,延迟是从numpy数组到memoryview的转换!我不确定这是否又是100%公平的,因为如果您键入,您可能还应该在cython中键入数组。但我想在任何情况下,它归结为一些转换(数组->memoryview或memoryview->数组),但无论如何,这都是很小的开销。根据你的建议,我尝试通过将im和pd复制到相应的numpy缓冲区类型来使测试更公平。我在test函数中执行此操作,然后将缓冲区类型传递给image_box1。然而,如果我试图将这些缓冲区类型传递给image_box1,我会得到编译错误“缓冲区类型仅允许作为函数局部变量”,我一直在试图找到该错误的解决方案,但似乎没有找到任何解决方案。我开始认为这是赛昂的限制。