我有一个简单的问题,为什么效率不高:
import numpy as np
cimport numpy as c_np
import cython
def function():
cdef c_np.ndarray[double, ndim=2] A = np.random.random((10,10))
cdef c_np.ndarray[double, ndim=1] slice
slice = A[1,:] #this line is marked as slow by the profiler cython -a
return
如何在没有开销的情况下在python中切割numpy矩阵。 在我的代码中,A是一个邻接矩阵,因此切片是我的路由算法中的邻居。
答案 0 :(得分:2)
注释器标记的行只是建议,不是基于实际的分析。我认为它使用了一个相对简单的启发式方法,比如python api调用的数量。它也没有考虑调用某些东西的次数 - 紧密循环中的黄线比一次调用的东西重要得多。
在这种情况下,你正在做的是相当有效的 - 一次调用numpy来获取切片数组,以及将该数组赋值给缓冲区。
生成的C代码看起来可能更好使用功能相同的memoryview语法,但您必须进行分析以确定这实际上是否更快。
%%cython -a
import numpy as np
cimport numpy as c_np
import cython
def function():
cdef double[:, :] A = np.random.random((10,10))
cdef double[:] slice
slice = A[1,:]
return
答案 1 :(得分:1)
冒着重复已经很好的答案(而不是回答问题!)的风险,我将指出与注释器的常见误解......黄色表示很多与python解释器的交互。那个(以及扩展后看到的代码)在优化时是一个非常有用的提示。
然而!引用有关代码优化的每篇文档的第一段:
首先配置文件,然后进行优化。说真的:不要猜测,首先介绍一下。
注释绝对不是个人资料。查看关于性能分析的cython文档,以及线性分析How to profile cython functions line-by-line
的答案作为一个例子,我的代码有一些亮黄色,它在大数组上调用一些numpy函数。实际上非常非常小的空间需要改进*因为python交互开销在这些大数组上进行了大量的计算。
*我或许可以通过直接使用numpy C接口来解决一些问题,但是再次通过大量计算进行摊销。