如何在IronPython 2.7中高效重复搜索短列表?
高效实现Revit短列表的大量重复搜索(IronPython 2.7)
核心优化思路
由于待搜索列表仅0-10项,但搜索次数远多于列表项数,提前预计算所有列表项的矩形边界是最有效的优化手段——预计算的开销几乎可以忽略,却能彻底避免每次搜索都重复计算Pt1/Pt2的中心与矩形范围,大幅节省总耗时。
数据结构拆分优化
把原始的ListToSearch拆分为预计算字典,键关联AcadEntID,值存储预计算好的矩形边界(轴对齐的最小/最大坐标)和原始列表项,这样每次搜索只需直接查询预计算数据,无需重复解析原始列表。
完整代码实现
import clr clr.AddReference('RevitAPI') from Autodesk.Revit.DB import Line, ElementId # 预计算轴对齐矩形边界(覆盖Pt1和Pt2的范围) def get_rect_bounds(pt1, pt2): min_x = min(pt1.X, pt2.X) max_x = max(pt1.X, pt2.X) min_y = min(pt1.Y, pt2.Y) max_y = max(pt1.Y, pt2.Y) min_z = min(pt1.Z, pt2.Z) max_z = max(pt1.Z, pt2.Z) return (min_x, max_x, min_y, max_y, min_z, max_z) # 预处理待搜索列表,生成预计算字典 def preprocess_search_list(raw_list): precomputed_data = {} for item in raw_list: # 假设ListToSearch的元素包含AcadEntID、Pt1、Pt2属性,按需调整 bounds = get_rect_bounds(item.Pt1, item.Pt2) precomputed_data[item.AcadEntID] = { 'bounds': bounds, 'source_item': item } return precomputed_data # 单次搜索逻辑 def match_revit_line(line_id, doc, precomputed): match_results = [] # 获取目标Revit线元素 line_element = doc.GetElement(ElementId(line_id)) if not isinstance(line_element, Line): return match_results # 提取线的两个端点 pt_a = line_element.GetEndPoint(0) pt_b = line_element.GetEndPoint(1) # 遍历预计算数据,判断端点是否在矩形范围内 for entry in precomputed.values(): min_x, max_x, min_y, max_y, min_z, max_z = entry['bounds'] # 判断两个端点是否至少一个在范围内,按需改为逻辑与(and) a_in_range = (min_x <= pt_a.X <= max_x) and (min_y <= pt_a.Y <= max_y) and (min_z <= pt_a.Z <= max_z) b_in_range = (min_x <= pt_b.X <= max_x) and (min_y <= pt_b.Y <= max_y) and (min_z <= pt_b.Z <= max_z) if a_in_range or b_in_range: match_results.append(entry['source_item']) return match_results # PyRevit集成使用示例 if __name__ == '__main__': doc = __revit__.ActiveUIDocument.Document # 替换为你的实际待搜索列表 ListToSearch = [] # 仅需预处理一次 precomputed_cache = preprocess_search_list(ListToSearch) Results = [] # 模拟大量重复搜索 for target_line_id in [1001, 1002, 1003, ...]: # 替换为实际搜索ID集合 current_matches = match_revit_line(target_line_id, doc, precomputed_cache) Results.extend(current_matches)
关键细节说明
- 预计算复用:预处理仅需执行一次,后续所有搜索都直接使用预计算好的矩形边界,避免重复计算
- 边界判断逻辑:代码默认判断「至少一个端点在矩形范围内」,如果业务要求两个端点都在,只需把
or改为and - Revit API适配:读取元素无需开启事务,若后续需要修改元素,需添加事务包裹
- 数据结构兼容:若
ListToSearch的元素属性名与代码不符,直接调整item.AcadEntID、item.Pt1等属性访问即可
内容的提问来源于stack exchange,提问作者Michelle
相关产品推荐
相关产品推荐

