Sort memoryview in Cython

为君一笑 提交于 2019-12-01 07:31:28

问题


How can I sort a memoryview in-place in Cython? Is there a built-in function that can do it? Right now I have to use a numpy array instead and use numpy's sort, which is very slow.


回答1:


To follow up on my comment, here are 3 options (numpy and a C and C++ standard library option)

from libcpp.algorithm cimport sort
from libc.stdlib cimport qsort

import numpy as np

def sort_numpy(double[:] a, kind):
    np.asarray(a).sort(kind=kind)

# needs to be compiled with C++        
def sort_cpp(double[::1] a):
    # a must be c continuous (enforced with [::1])
    sort(&a[0], (&a[0]) + a.shape[0])

# The C version requires a comparator function
# which is a little slower since it requires calling function pointers
# and passing pointers rather than numbers
cdef int cmp_func(const void* a, const void* b) nogil:
    cdef double a_v = (<double*>a)[0]
    cdef double b_v = (<double*>b)[0]
    if a_v < b_v:
        return -1
    elif a_v == b_v:
        return 0
    else:
        return 1

def sort_c(double[:] a):
    # a needn't be C continuous because strides helps
    qsort(&a[0], a.shape[0], a.strides[0], &cmp_func)

The results you'll will depend on which C/C++ standard library you're using so don't read too much into my results. For a 1000 long array (sorted 5000 times) I get:

np quick:  0.11296762199890509
np merge:  0.20624926299933577
np heap:  0.2944786230000318
c++:  0.12071316699984891
c:  0.33728832399901876

i.e. the numpy version is fastest. For a 100 long array I get

np quick:  0.022608489000049303
np merge:  0.023513408999860985
np heap:  0.024136934998750803
c++:  0.008449130998997134
c:  0.01909676999821386

i.e if you're sorting lots of small arrays, the overhead of calling numpy sort is large and you should use C++ (or possibly C). If you're sorting large arrays you may find it hard to beat numpy.



来源:https://stackoverflow.com/questions/38254146/sort-memoryview-in-cython

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!