【问题标题】:Sort memoryview in Cython在 Cython 中对内存视图进行排序
【发布时间】:2016-07-07 19:51:15
【问题描述】:

如何在 Cython 中对内存视图进行就地排序?有没有内置函数可以做到这一点?现在我必须改用numpy 数组并使用numpy 的排序,这非常慢。

【问题讨论】:

  • numpy.sort 的性能问题还是将memoryview 复制到numpy 数组的成本问题?如果是后者,那么 np.asarray(memview) 应该可以在没有副本的情况下工作。
  • @DavidW 是numpy.sort的性能问题
  • 您可以尝试告诉 numpy 使用不同的算法(我认为它可以选择 3)。如果这没有帮助,您可以使用 C++ 标准库 cplusplus.com/reference/algorithm/sort。您可以将它与指针一起使用,因此它类似于sort(&memview[0],&memview[length])(请注意,您将它传递到末尾的一个元素。不过,您需要使用 C++ 编译它。

标签: python cython memoryview


【解决方案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 sort 的开销很大,您应该使用 C++(或者可能是 C)。如果您正在对大型数组进行排序,您可能会发现很难击败 numpy。

【讨论】:

  • 完美,谢谢。调用 numpy 的开销给我带来了问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
相关资源
最近更新 更多