Python元素访问性能 作为一个长时间的C++开发人员,我刚刚开始在Python中研究算法。我目前正在分析我的代码,以了解如何在Python中高效编程。有一件事特别突出,我很乐意得到专家的解释

Python元素访问性能 作为一个长时间的C++开发人员,我刚刚开始在Python中研究算法。我目前正在分析我的代码,以了解如何在Python中高效编程。有一件事特别突出,我很乐意得到专家的解释,python,performance,Python,Performance,我为光线三角形交点编写了此包装函数: def rayIntersectsTriangle( origin , direction , meshData , poly , worldCoordinateVertices ): return mathutils.geometry.intersect_ray_tri( worldCoordinateVertices[ meshData.loops[ poly.loop_start ].vertex_index ],

我为光线三角形交点编写了此包装函数:

def rayIntersectsTriangle( origin , direction , meshData , poly , worldCoordinateVertices ):
    return mathutils.geometry.intersect_ray_tri( worldCoordinateVertices[ meshData.loops[ poly.loop_start ].vertex_index ],
                                                 worldCoordinateVertices[ meshData.loops[ poly.loop_start + 1 ].vertex_index ],
                                                 worldCoordinateVertices[ meshData.loops[ poly.loop_start + 2 ].vertex_index ],
                                                 direction , origin ) != None
在分析(使用cProfile)多次执行此函数的代码时,我得到以下结果:

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
15694126   22.314    0.000   25.812    0.000 ****.py:176(rayIntersectsPoly)
[...]
15694126    3.497    0.000    3.497    0.000 {built-in method mathutils.geometry.intersect_ray_tri}
为什么这个包装会增加这么多开销?我唯一能看到的就是数组元素的访问。来自C++的这真的让我困惑:D<P> 在此方面的任何帮助都将不胜感激。我想尽快得到我的算法


提前谢谢!干杯

由于
mathutils.geometry.intersect\u ray\u tri()
的速度太快,所以时间看起来比较长。该方法在扩展中实现,并以本机速度执行

该方法的Python时间为:

  • 创建新的函数框架(仅使用一个表达式,时间占比较大的比例)
  • 全局名称查找(这些是根据映射进行的,本地名称使用数组)
  • 属性查找,如
    mathutils.geometry
    mathutils.geometry.intersect\u ray\u tri
    poly.loop\u start
  • 索引,所以
    世界协调[…]
通过将其中一些结果缓存在本地名称或默认参数中,您可以加快速度:

def rayIntersectsTriangle(
        origin, direction, meshData, poly, worldCoordinateVertices
        _intersect_ray_tri=mathutils.geometry.intersect_ray_tri):
    loop_start = poly.loop_start
    meshData_loops = meshData.loops
    return _intersect_ray_tri(
        worldCoordinateVertices[meshData_loops[loop_start].vertex_index],
        worldCoordinateVertices[meshData_loops[loop_start + 1].vertex_index],
        worldCoordinateVertices[meshData_loops[loop_start + 2].vertex_index],
        direction, origin) is not None
我还使用了
不是None
;这是一个指针操作,建议用于测试
None
单例

这将使8个属性查找下降到2个,并删除
数学的全局名称查找


尽管如此,这些都是微观优化,只有在它们确实有影响时才进行(例如,在代码中经常调用该方法)。如果这真的是一个瓶颈,你可以考虑把它作为一个简单的路径,把这个代码转换成一个编译的扩展,它也可以在原生的速度下运行。

参见…和BTW,如果以数学为中心的工作负载的运行时性能是你的首要目标,Python可能不是你的语言。我可以建议你还是?(茱莉亚的页面同时涵盖了这两个方面)。太棒了。谢谢你的资源。我目前正在为Blender开发一个插件,所以我真的没有Pythonow的替代品,非常感谢。多么详细和快速的回答啊。这无疑给了我很多洞察力