ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-12-08 03:07:42  阅读:319  来源: 互联网

标签:cython c-3 python


因此,我在Python脚本中有一段对时间要求严格的代码,因此我决定编写一个Cython模块(具有一个功能-我需要的全部)来替换它.不幸的是,我从Cython模块(在Python脚本中调用的)调用的函数的执行速度几乎不像我在各种其他情况下测试的那样快.请注意,由于合同法的限制,我无法共享代码!请参阅以下情况,并将其作为对我的问题的初步描述:

(1)使用Python解释器执行Cython函数,以导入模块并运行该函数.运行速度相对较快(在约100个单独的测试中约为0.04秒,而原始的约为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循环的(非常小的)开销.我了解这可能是不可能的(例如,需要来自全局/更大范围的引用),但是您值得进行一些研究.祝好运!

标签:cython,c-3,python
来源: https://codeday.me/bug/20191208/2088461.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有