Indexing Cython针对numpy阵列的额外键入和cimport会降低性能吗?
下面是我写的两个简单的Cython方法。在g_cython()方法中,我对numpy数组a和b使用了额外的类型,但令人惊讶的是,g_cython()比g_less_cython()慢两倍。我想知道为什么会这样?我想加上它会使a和b上的索引速度更快吗 另外,我知道这两个函数都可以在numpy中矢量化——我只是在探索cython的优化技巧Indexing Cython针对numpy阵列的额外键入和cimport会降低性能吗?,indexing,numpy,cython,Indexing,Numpy,Cython,下面是我写的两个简单的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
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(百分位数)=100时
我测试了你的代码,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
我关闭了boundscheck和wraparound标志:
@cython.boundscheck(False)
@cython.wraparound(False)
def g_cython(np.ndarray[np.int_t, ndim = 1] a, percentile):
....
差异并不显著,因为np.searchsorted(percentile,a[i])的调用是占用大部分CPU的关键部分。对我来说,你的代码不是按照编写的方式构建的-你需要一个numpy的导入和cimport,在第4行,你需要将类似于
dtype=int
的东西传递给np.zero
,否则它会创建一个双精度数组(尽管这可能取决于cython的版本?)。此外,如果您提供了一个典型的使用示例,也会有所帮助。无论如何,如果您想比较cython在每种情况下所做的工作,您可以使用cython-a
构建该文件,该文件提供了一个格式良好的html文件,在该文件中,单击python代码行可以显示相应生成的C代码。@James感谢您的回复。我跳过了cimport和import部分,因为我认为在代码中发布这些行会分散注意力。我添加了数据类型部分。谢谢您的回复。即使对于你的测试用例,我仍然没有得到你的结果。g_less_cython()更快。我发布了我的测试用例。顺便问一下,你使用的是什么平台?我不认为time.clock()有多高的精确度?我用的是windows XP,time.clock()足够精确,
@cython.boundscheck(False)
@cython.wraparound(False)
def g_cython(np.ndarray[np.int_t, ndim = 1] a, percentile):
....