加快Cython的速度。列表与Numpy数组

时间:2019-07-09 13:15:00

标签: python cython

我目前正在尝试加快Cython例程的速度,该例程高度依赖列表。通常,我想提高这些列表上索引的速度。

根据文档,建议将Numpy数组与memoryviews一起使用。

https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html

但是,当我将列表更改为numpy数组(它们中的大多数只是整数)时,代码会变慢。 我想更好地理解为什么会这样,因为我希望数组会比列表快得多。

我无法显示我正在使用的确切代码,但是我将使用一个示例来传达我的问题。

所以可以说我有这三个函数,它们计算列表中元素的数量。 示例:如果列表为:

test_list = [1, 2, 3, 4, 1, 1, 3, 4]

然后输出为[3,1,2,2]。

def counter(test_list):
""" The Counter was imported from collections naturally """
    output = [0] * len(set(test_list))
    for key, value in Counter(test_list).items():
        output[key - 1] = value
    return output

现在有两个计算相同内容的cython函数:

def cython_counter_collections(test_list):

    cdef int key, value

    output = [0] * len(set(test_list))
    for key, value in Counter(test_list).items():
        output[key - 1] = value
    return output

def cython_counter_manual(test_list):

    cdef long[:] new_test_list = np.array(test_list)
    cdef int size, val, i, uniques_size
    size = new_test_list.shape[0]
    uniques_size = np.unique(new_test_list).shape[0]

    i = 0
    output = [0] * uniques_size
    while i < size:
        val = new_test_list[i]
        output[val-1] += 1
        i+=1

    return output

对于最后一个函数,我使用import和cimport numpy作为np。

我假设最后一个函数cython_counter_manual将被禁闭,因为我使用的是numpy数组,并且不使用任何Python调用。 例如,我使用timeit来测量时间

print(timeit("counter(test_list)", globals=globals(), number=n_its))

所有功能的结果为:

Python Code
3.12014272399756 s

Cython Counter Collections
2.883361326999875 s

Cython Counter Manual
11.205707081000583 s

为什么会这样?它怎么变得这么慢? 谢谢!

0 个答案:

没有答案