用Cython的差(ER)性能numpy的阵列memoryview相比,C数组 [英] Poor(er) performance of Cython with NumPy array memoryview compared to C arrays

查看:428
本文介绍了用Cython的差(ER)性能numpy的阵列memoryview相比,C数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到从<一个一个pretty怪异的结果href=\"http://nbviewer.ipython.org/github/rasbt/One-Python-benchmark-per-day/blob/master/ipython_nbs/day4_python_cython_numba.ipynb?create=1\"相对=nofollow>基准

这些都是一个冒泡实施的所有不同的口味,并以n最快方法= 10 ^ 4在内部转换一个Python名单C数组。相反,黄线对应于code,其中我使用numpy的阵列,memoryview。我的预期结果是,反之亦然。我(和同事)反复基准几次,总是得到相同的结果。也许有人有一个想法是怎么回事...

在图中的黑线将对应于code:

  %%用Cython
cimport用Cython
从libc.stdlib cimport的malloc,免费高清cython_bubblesort_clist(a_list)将:
    
    在用Cython实现冒泡排序内部的
    Python列表对象和C数组之间的转换。    
    CDEF为int * c_list
    c_list =&LT; INT *&GT;的malloc(LEN(a_list)将* cython.sizeof(INT))
    CDEF诠释计数,I,J#静态类型声明
    数= LEN(a_list)将    #转换Python列表到C数组
    因为我在范围内(计数):
        c_list [I] =的a_list [I]    因为我在范围内(计数):
        在范围Ĵ(1,计数):
            如果c_list [J] LT; c_list [J-1]:
                c_list [J-1],c_list [J] = c_list [J],c_list [J-1]    #转换数组c回Python列表
    因为我在范围内(计数):
        的a_list [I] = c_list [I]    免费(c_list)
    返回的a_list

和粉红色的线,这个code:

  %%用Cython
导入numpy的是NP
cimport numpy的是NP
cimport用Cython
高清cython_bubblesort_numpy(长[:] np_ary):
    
    在用Cython实现冒泡排序与numpy的memoryview的。    
    CDEF诠释计数,I,J#静态类型声明
    数= np_ary.shape [0]    因为我在范围内(计数):
        在范围Ĵ(1,计数):
            如果np_ary [J] LT; np_ary [J-1]:
                np_ary [J-1],np_ary [J] = np_ary [J],np_ary [J-1]    返回np.asarray(np_ary)


解决方案

由于在意见提出上述,我添加了装饰

  %%用Cython
导入numpy的是NP
cimport numpy的是NP
cimport用Cython
@ cython.boundscheck(假)
@ cython.wraparound(假)
cpdef cython_bubblesort_numpy(长[:] np_ary):
    
    在用Cython实现冒泡排序与numpy的memoryview的。    
    CDEF诠释计数,I,J#静态类型声明
    数= np_ary.shape [0]    因为我在范围内(计数):
        在范围Ĵ(1,计数):
            如果np_ary [J] LT; np_ary [J-1]:
                np_ary [J-1],np_ary [J] = np_ary [J],np_ary [J-1]    返回np.asarray(np_ary)

和结果更是我目前预计:)

I encountered a pretty weird result from a benchmark

Those are all different flavors of a bubblesort implementation, and the fastest approach at n=10^4 is converting a Python lists to C arrays internally. In contrast, the yellow line corresponds to code where I am using NumPy arrays with memoryview. I am expected the results to be vice versa. I (and colleagues) repeated the benchmark a couple of times and always got the same results. Maybe someone has an idea of what is going on here ...

The black line in the plot would correspond to the code:

%%cython
cimport cython
from libc.stdlib cimport malloc, free

def cython_bubblesort_clist(a_list):
    """ 
    The Cython implementation of bubble sort with internal
    conversion between Python list objects and C arrays.

    """
    cdef int *c_list
    c_list = <int *>malloc(len(a_list)*cython.sizeof(int))
    cdef int count, i, j # static type declarations
    count = len(a_list)

    # convert Python list to C array
    for i in range(count):
        c_list[i] = a_list[i]

    for i in range(count):
        for j in range(1, count):
            if c_list[j] < c_list[j-1]:
                c_list[j-1], c_list[j] = c_list[j], c_list[j-1]

    # convert C array back to Python list
    for i in range(count):
        a_list[i] = c_list[i]

    free(c_list)
    return a_list

and the pink line to this code:

%%cython
import numpy as np
cimport numpy as np
cimport cython
def cython_bubblesort_numpy(long[:] np_ary):
    """ 
    The Cython implementation of bubble sort with NumPy memoryview.

    """
    cdef int count, i, j # static type declarations
    count = np_ary.shape[0]

    for i in range(count):
        for j in range(1, count):
            if np_ary[j] < np_ary[j-1]:
                np_ary[j-1], np_ary[j] = np_ary[j], np_ary[j-1]

    return np.asarray(np_ary)

解决方案

As suggested in the comments above, I added the decorators

%%cython
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False) 
@cython.wraparound(False)
cpdef cython_bubblesort_numpy(long[:] np_ary):
    """ 
    The Cython implementation of bubble sort with NumPy memoryview.

    """
    cdef int count, i, j # static type declarations
    count = np_ary.shape[0]

    for i in range(count):
        for j in range(1, count):
            if np_ary[j] < np_ary[j-1]:
                np_ary[j-1], np_ary[j] = np_ary[j], np_ary[j-1]

    return np.asarray(np_ary)

and the results are more what I expected now :)

这篇关于用Cython的差(ER)性能numpy的阵列memoryview相比,C数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆