C语言 在 Python 脚本中调用 Cython 函数时出现意外的性能损失



所以我在Python脚本中有一个时间关键的代码部分,我决定编写一个Cython模块(有一个函数 - 我需要的(来替换它。不幸的是,我从 Cython 模块(我在 Python 脚本中调用(调用的函数的执行速度并不像我在各种其他场景中测试的那样快。请注意,由于合同法,我不能共享代码本身!请参阅以下案例,并将它们作为我问题的初始描述:

(1( 使用 Python 解释器导入模块并运行函数来执行 Cython 函数。运行相对较快(~0.04 秒在 ~100 个单独的测试中,而原来的 ~0.24 秒(。

(2(在"全局"级别(即不在任何函数内部(调用Python脚本中的Cython函数。速度与案例 (1( 相同。

(3(在Python脚本中调用Cython函数,在我的Python脚本的主函数中使用Cython函数;在全局和本地命名空间中使用Cython函数进行测试,所有函数的速度都与案例(1(相同。

(4( 与 (3( 相同,但在所述 Python 函数内的简单 for 循环中。速度与案例 (1( 相同。

(5(问题!与 (4( 相同,但在另一个 for 循环中:Cython 函数的执行时间(无论是全局调用还是本地调用(膨胀到其他情况的 ~10 倍,这就是我需要调用函数的地方。关于这个循环没有什么奇怪的报告,我测试了这个循环的所有组件(调整/删除我能做的(。我还尝试使用"while"循环来咯咯笑,但无济于事。

"我还没有尝试过的一件事是让这个最里面的循环成为一个函数,然后从那里开始。 编辑:刚刚尝试过这个 - 没有运气。

感谢您的任何建议 - 我深感遗憾无法分享我的代码......这让我的灵魂有点痛,但我的客户就是不能让这段代码四处游荡。如果还有其他信息可以提供,请告诉我!

-真正的问题和初步(丑陋的(解决方案-

事实证明,在这种情况下,最好的提示是显而易见的(像往常一样(:不是for循环导致了问题;为什么会这样?经过几次测试,很明显我调用 Cython 函数的方式有些错误,因为我可以在其他地方调用它(使用与"真正的"Cython 函数不同的输入变量(,而不会造成性能损失问题。

根本问题:数据类型。我编写了我的 Cython 函数,以期待一个充满标准浮点的列表。不幸的是,我的代码这样做了:

function_input = list(numpy_array_containing_npfloat64_data) # yuck.
type(function_input[0]) = numpy.float64
output = Cython_Function(function_input)

在 Cython 函数中:

def Cython_Function(list function_input):
    cdef many_vars
    """process lots of vars expecting C floats""" # Slowness from converting numpy.float64's --> floats???
    type(output) = list
    return output

我知道我可以更多地使用 Cython 函数中的类型,我可能会很好地这样做来防止不得不"列出"现有的 numpy 数组。无论如何,这是我当前的解决方案:

function_input = [float(x) for x in function_input]

我欢迎任何反馈和改进建议。function_input numpy 数组实际上并不需要 numpy.float64 的精度,但在传递给我的 Cython 函数之前,它确实被使用了几次。

可能是,虽然单独使用 Cython 实现的每个函数调用都

比其相应的 Python 函数快,但 Cython 函数调用中有更多的开销,因为它必须在模块命名空间中查找名称。您可以先尝试将函数分配给本地可调用对象,例如:

from module import function
def main():
    my_func = functon
    for i in sequence:
        my_func()

如果可能的话,你应该尝试在 Cython 函数中包含循环,这会将 Python 循环的开销减少到编译的 C 循环的(非常小的(开销。我知道这可能是不可能的(即需要来自全局/更大范围的参考(,但值得您进行一些调查。 祝你好运!

function_input = list(numpy_array_containing_npfloat64_data)
def Cython_Function(list function_input):
    cdef many_vars

我认为问题在于使用 numpy 数组作为列表......你不能使用 np.ndarray 作为 Cython 函数的输入吗?

def Cython_Function(np.ndarray[dtype=np.float64] input):
   ....

相关内容

  • 没有找到相关文章

最新更新