如何优化Python的add_may_go函数,提升其运行速度?
优化围棋可落子位置计算函数的建议
以下是针对add_may_go函数的具体优化方案,贴合你提到的场景:
缓存重复计算结果
由于函数需要执行数百次,很多位置可能被重复查询。用字典做缓存,避免重复计算:_cache = {} def add_may_go(x, y): if (x, y) in _cache: return _cache[(x, y)] # 原计算逻辑 result = 计算得到的数量 _cache[(x, y)] = result return result注意:如果
public_grid会动态更新,需要在更新时清空_cache。将
huge_may_go转换为集合
列表的成员查询是O(n)复杂度,改成集合后查询速度变为O(1):huge_may_go_set = set(huge_may_go)后续判断位置是否已记录时,直接用
(nx, ny) in huge_may_go_set替代列表查询。优化
public_grid的访问效率
普通Python列表的索引访问本身比numpy数组在单元素查询时更快,你之前用numpy变慢可能是因为引入了不必要的数组转换或批量操作。可以提前把所有已落子位置存入集合:occupied = {(x, y) for x in range(board_order) for y in range(board_order) if public_grid[x][y] == 1}后续判断位置是否被占用时,直接用
(nx, ny) in occupied,比每次索引public_grid[nx][ny]更高效,尤其在循环中频繁调用时。提前做边界判断,减少无效计算
预定义周边方向列表,循环时先判断坐标是否在棋盘范围内,不符合直接跳过:directions = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] def add_may_go(x, y): count = 0 local_board = board_order for dx, dy in directions: nx = x + dx ny = y + dy if 0 <= nx < local_board and 0 <= ny < local_board: if (nx, ny) not in occupied and (nx, ny) not in huge_may_go_set: count +=1 # 若需要添加到huge_may_go,直接操作集合:huge_may_go_set.add((nx, ny)) return count用局部变量替代全局变量访问
Python访问全局变量的开销比局部变量高,在函数内部将全局变量赋值为局部变量,减少循环中的查找开销:def add_may_go(x, y): local_board_order = board_order local_occupied = occupied local_may_go_set = huge_may_go_set directions = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] count = 0 for dx, dy in directions: nx = x + dx ny = y + dy if 0 <= nx < local_board_order and 0 <= ny < local_board_order: if (nx, ny) not in local_occupied and (nx, ny) not in local_may_go_set: count +=1 return count避免不必要的列表操作
如果huge_may_go仅用于记录已统计的位置,直接用集合存储即可,不需要维护列表;如果最终需要列表形式,只在最后一次性转换,减少频繁append的开销。
内容的提问来源于stack exchange,提问作者shunyi sui
相关产品推荐
相关产品推荐

