2016-07-07 21 views
1

Cythonでメモリビューをインプレースでソートするにはどうすればよいですか?それを行うことができる組み込み関数はありますか?今はnumpy配列を代わりに使用し、numpyの並べ替えを使用する必要があります。これは非常に遅いです。ここでは、私のコメントをフォローアップするためにCythonでメモリビューをソート

+0

'numpy.sort'のパフォーマンスやmemoryviewをnumpy配列にコピーするコストに問題はありますか?後者の場合、 'np.asarray(memview)'はコピーなしで動作するはずです。 – DavidW

+0

@DavidW 'numpy.sort'の性能に問題があります –

+3

numpyに別のアルゴリズムを使用するように伝えてみることもできます(3つの選択肢があると思います)。それが助けにならないなら、C++標準ライブラリhttp://www.cplusplus.com/reference/algorithm/sort/を使うことができます。ポインタで使うことができるので、 'sort(&memview [0]、memview [length])'のようになります(最後の要素を1つ渡すことに注意してください。 – DavidW

答えて

4

は、3つのオプション(numpyのとCとC++標準ライブラリオプション)

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) 

あなたはC/C++標準ライブラリたに依存しますよ結果、あなたがしているされています私の結果にあまり読み込まないでください。 1000年の長い配列(5000回をソート)のために私は得る:

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

すなわちnumpyのバージョン最速です。 100 long配列のために私は

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

すなわちを得るあなたは小さな配列の多くをソートしている場合は、numpyのソートを呼び出しのオーバーヘッドが大きく、あなたはC++(あるいはC)を使用する必要があります。大きな配列をソートしている場合は、numpyにぶつかりにくいかもしれません。

+0

パーフェクト、感謝。numpyを呼び出すオーバーヘッドは私のために問題を引き起こしていた –

関連する問題