You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化基于二维空间点的树状grid节点搜索方法

结构化网格点定位:平方判断逻辑与性能优化

关于平方判断的原因

从代码逻辑来看,参数r实际代表的是径向距离的平方(比如极坐标下的r² = x² + y²),而xmin/xmax是径向方向的线性边界值。使用平方对比而非开方后对比,核心目的是避免耗时的开方浮点运算——开方操作的计算成本远高于乘法,直接用平方值做比较能显著减少单步判断的计算量,提升整体遍历效率。

如果你的场景中r是实际径向距离(而非平方值),当前的判断逻辑是错误的,需要改为cout['xmin'] <= np.sqrt(r) <= cout['xmax'],但现有代码的设计显然是让r传入平方值,以此换取性能。

性能优化建议

目前启用Numba-JIT后耗时14秒,但仍有较大优化空间,以下是针对性的优化点:

1. 预计算平方值,消除重复运算

当前函数中每次判断都要重复计算xmin²和xmax²,这是最大的性能损耗源之一。建议直接在grid结构化数组中新增xmin_sq和xmax_sq字段,一次性完成所有节点的平方计算并存储。定位函数中直接读取预计算的平方值,省去大量重复的乘法操作。

2. 优化数组访问模式

Numba对连续numpy数组的访问效率远高于结构化数组的字段访问:

  • 将grid的各个字段提取为独立的一维数组(比如grid_xmin_sq = grid['xmin_sq']、grid_ymin = grid['ymin']),在函数中直接使用这些数组进行索引判断。
  • 提前提取当前节点的子节点ID列表(child_ids = cout['children'][:cout['nChildren']]),避免在循环中重复执行切片和索引操作。

3. 精简循环与分支逻辑

  • 将NMAX设置为树的实际最大深度(而非1e6),避免不必要的循环范围检查。
  • 把点在单元格内的判断逻辑封装为一个小的辅助函数,Numba会自动内联这类函数,减少代码冗余并提升执行效率。
  • 尽量减少回溯逻辑:如果起始节点c_index是包含目标点的节点,可以去掉回溯到父节点的分支,只保留向下遍历子节点的逻辑;若起始节点可能不包含点,建议直接从根节点开始遍历,避免回溯带来的分支开销。

4. 最大化Numba优化效果

使用@numba.njit(fastmath=True, cache=True)装饰函数,开启快速数学运算和缓存功能。如果能提前为grid指定明确的结构化类型(而非依赖自动推断),Numba的优化会更彻底。

原函数代码

def locate_photon_cell_mirror(r, z, c_index, grid):
    NMAX = 1000000
    found = False
    cout_index = c_index
    abs_z = np.abs(z)

    for j in range(NMAX):
        cout = grid[cout_index]
        if (cout['xmin']**2 <= r and
            cout['xmax']**2 >= r and 
            cout['ymin']    <= abs_z and
            cout['ymax']    >= abs_z):
            if (cout['nChildren'] == 0):
                found = True
                return cout_index, found
            
            flag = True

            for i in range(cout['nChildren']):
                child_cell = grid[cout['children'][i]]
                if (child_cell['xmin']**2 <= r and 
                    child_cell['xmax']**2 >= r and 
                    child_cell['ymin']    <= abs_z and 
                    child_cell['ymax']    >= abs_z):

                    cout_index = cout['children'][i]
                    flag = False
                    break
            
            if (flag):
                cout_index = -999999
                return cout_index, found
        
        else:
            cout_parent = cout['parent']
            if cout_parent != -1:
                cout_index = cout_parent
            else:
                cout_index = -999999
                return cout_index, found
    
    cout_index = -999999

    return cout_index, found

内容的提问来源于stack exchange,提问作者matts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:45:59