【问题标题】:Cython additional typing and cimport for numpy array slow down the performance?numpy 数组的 Cython 额外输入和 cimport 会降低性能?
【发布时间】:2012-02-01 13:42:12
【问题描述】:

下面是我写的两个简单的 Cython 方法。在 g_cython() 方法中,我对 numpy 数组 a 和 b 使用了额外的类型,但令人惊讶的是 g_cython() 比 g_less_cython() 慢两倍。我想知道为什么会这样?我认为添加这会使 a 和 b 上的索引更快?

附言。我知道这两个函数都可以在 numpy 中进行矢量化——我只是在探索 cython 优化技巧。

import numpy as np; 
cimport numpy as np;

def g_cython(np.ndarray[np.int_t, ndim = 1] a, percentile):
    cdef int i
    cdef int n = len(a)
    cdef np.ndarray[np.int_t, ndim = 1] b = np.zeros(n, dtype = 'int')
    for i in xrange(n):
        b[i] = np.searchsorted(percentile, a[i])
    return b


def g_less_cython(a, percentile):
    cdef int i
    b = np.zeros_like(a)
    for i in xrange(len(a)):
        b[i] = np.searchsorted(percentile, a[i])
    return b

我的测试用例是 len(a) == 1000000 和 len(percentile) = 100

def main3():
    n = 100000
    a = np.random.random_integers(0,10000000,n)
    per = np.linspace(0, 10000000, 101)

    q = time.time()
    b = g_cython(a, per)
    q = time.time() - q
    print q

q = time.time()
bb = g_less_cython(a, per)
q = time.time() - q
print q

【问题讨论】:

  • 对我来说,你的代码并没有像写的那样构建——你需要一个 numpy 的 import 和 cimport,在第 4 行,你需要将 dtype=int 之类的东西传递给 np.zeros,否则它创建一个双精度数组(尽管这可能取决于 cython 的版本?)。此外,如果您提供一个典型的使用示例,也会有所帮助。无论如何,如果您想比较 cython 在每种情况下所做的事情,您可以使用 cython -a 构建文件,它会为您提供一个格式良好的 html 文件,其中单击 python 代码行会显示相应的生成的 C 代码。
  • @James 感谢您的回复。我跳过了 cimport 和 import 部分,因为我认为在代码中发布这些行会分散注意力。我添加了 dtype 部分。

标签: indexing numpy cython


【解决方案1】:

我测试了你的代码,g_cython 比 g_less_cython 稍快。

这里是测试代码

import pyximport; pyximport.install()
import search_sorted
import numpy as np
import time
x = np.arange(100000, dtype=np.int32)
y = np.random.randint(0, 100000, 100000)

start = time.clock()
search_sorted.g_cython(y, x)
print time.clock() - start

start = time.clock()
search_sorted.g_less_cython(y, x)
print time.clock() - start

输出是:

0.215430514708
0.259622599945

我关闭了边界检查和环绕标志:

@cython.boundscheck(False)
@cython.wraparound(False)
def g_cython(np.ndarray[np.int_t, ndim = 1] a, percentile):
    ....

区别并不明显,因为 np.searchsorted(percentile, a[i]) 的调用是占用大部分 CPU 的关键部分。

【讨论】:

  • 感谢您的回复。即使对于您的测试用例,我仍然没有得到您的结果。 g_less_cython() 仍然更快。我发布了我的测试用例。
  • 顺便问一下你用的是什么平台?我不认为 time.clock() 提供了很高的准确性?
  • 我用的是windows XP,time.clock()够准确,docs.python.org/library/time.html?time.clock#time.clock
猜你喜欢
  • 2014-11-02
  • 1970-01-01
  • 2017-11-24
  • 2011-02-06
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
相关资源
最近更新 更多