Как я могу отсортировать memoryview на месте в Cython? Есть ли встроенная функция, которая может это сделать? Прямо сейчас я должен использовать массив numpy
и использовать сортировку numpy
, что очень медленно.
Сортировка memoryview в Cython
Ответы (1)
Чтобы продолжить мой комментарий, вот 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 я получаю
np quick: 0.022608489000049303 np merge: 0.023513408999860985 np heap: 0.024136934998750803 c++: 0.008449130998997134 c: 0.01909676999821386
т.е. если вы сортируете множество небольших массивов, накладные расходы на вызов сортировки numpy велики, и вам следует использовать C ++ (или, возможно, C). Если вы сортируете большие массивы, вам может быть сложно превзойти numpy.
person
DavidW
schedule
09.07.2016
Отлично, спасибо. Накладные расходы на вызов numpy вызывали у меня проблемы
- person C_Z_; 13.07.2016
numpy.sort
или в стоимости копирования memoryview в массив numpy? Если последнее, тоnp.asarray(memview)
должен работать без копии. - person DavidW   schedule 07.07.2016numpy.sort
- person C_Z_   schedule 07.07.2016sort(&memview[0],&memview[length])
(обратите внимание, что вы передаете ему один элемент после конца. Однако вам нужно будет скомпилировать его с помощью C ++. - person DavidW   schedule 07.07.2016