perf: warehouse build_tree 改为 Map 分组内存组装,消除 O(N²) 递归全扫(tree TTFB 1.7s→0.08s)

This commit is contained in:
yueli
2026-09-04 15:10:38 +08:00
parent 3bd19c1ab5
commit bc6e97ae97

View File

@ -10,23 +10,25 @@ warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/api/v1/warehouse')
def build_tree(nodes, parent_id=None):
"""
将平铺的数据构建为树形结构
将平铺的数据构建为树形结构O(N) 内存组装,避免递归时每层全量扫描导致 O(N²)
做法:先把全部节点按 parent_id 分组到 Map再从根出发逐层用 Map 取子节点组装。
每个节点只被处理一次,显著快于"每次递归 for 遍历全表"的旧实现。
"""
tree = []
by_parent = {}
for node in nodes:
if node.parent_id == parent_id:
children = build_tree(nodes, node.id)
node_dict = node.to_dict()
if children:
# 子节点按 name 升序排序
children_sorted = sorted(children, key=lambda x: x.get('name', ''))
node_dict['children'] = children_sorted
else:
node_dict['children'] = []
tree.append(node_dict)
# 当前层级按 name 升序排序
tree_sorted = sorted(tree, key=lambda x: x.get('name', ''))
return tree_sorted
by_parent.setdefault(node.parent_id, []).append(node)
def assemble(pid):
kids = sorted(by_parent.get(pid, []), key=lambda x: (x.name or ''))
out = []
for k in kids:
d = k.to_dict()
d['children'] = assemble(k.id)
out.append(d)
return out
return assemble(parent_id)
@warehouse_bp.route('/tree', methods=['GET'])