From 320dfa23f3a1edc2e8f2dc5095b1c631cc5ae28c Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Tue, 14 Oct 2025 12:15:29 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E7=A9=BA=E9=97=B4=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E5=A4=8D=E7=94=A8=E5=87=A0=E4=BD=95=E5=AF=B9=E8=B1=A1=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E9=81=BF=E5=85=8D=E9=87=8D=E5=A4=8D=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题描述: - BuildAllGeometryItemsCache() 已经遍历模型树获取290个几何对象 - SpatialIndexManager 又重新遍历一次模型树获取290个对象 - 重复工作导致性能浪费 优化方案: 1. 在 ClashDetectiveIntegration 中添加 GetAllGeometryItemsCache() 公开方法 2. SpatialIndexManager 调用该方法获取缓存的几何对象列表 3. 避免重复遍历模型树,提升性能 技术细节: - GetAllGeometryItemsCache() 返回列表副本保证线程安全 - 添加缓存不存在时的回退逻辑(保险措施) - 日志输出改为"从缓存获取"以明确数据来源 性能提升: - 减少模型树遍历次数:2次 → 1次 - 优化空间索引构建流程 - 所有碰撞检测和空间索引共享同一个几何对象列表 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../Collision/ClashDetectiveIntegration.cs | 23 +++++++++++++------ src/Core/Spatial/SpatialIndexManager.cs | 17 ++++++++++---- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Core/Collision/ClashDetectiveIntegration.cs b/src/Core/Collision/ClashDetectiveIntegration.cs index 0782127..ac86bc2 100644 --- a/src/Core/Collision/ClashDetectiveIntegration.cs +++ b/src/Core/Collision/ClashDetectiveIntegration.cs @@ -1186,9 +1186,6 @@ namespace NavisworksTransport } - /// - /// 构建几何对象列表缓存,一次性获取所有几何对象 - /// /// /// 构建几何对象列表缓存,一次性获取所有几何对象 /// @@ -1197,17 +1194,17 @@ namespace NavisworksTransport lock (_cacheLock) { if (_allGeometryItemsCache != null) return; // 双重检查锁定 - + var cacheStopwatch = new System.Diagnostics.Stopwatch(); cacheStopwatch.Start(); - + try { var allItems = Application.ActiveDocument.Models.RootItemDescendantsAndSelf .Where(item => item.HasGeometry); - + _allGeometryItemsCache = allItems.ToList(); - + cacheStopwatch.Stop(); LogManager.Info($"几何对象列表缓存构建完成,耗时: {cacheStopwatch.ElapsedMilliseconds}ms"); LogManager.Info($" - 缓存对象总数: {_allGeometryItemsCache.Count} 个"); @@ -1219,6 +1216,18 @@ namespace NavisworksTransport } } } + + /// + /// 获取几何对象缓存(供外部使用) + /// + /// 几何对象列表的副本,如果缓存不存在则返回null + public static List GetAllGeometryItemsCache() + { + lock (_cacheLock) + { + return _allGeometryItemsCache?.ToList(); // 返回副本以保证线程安全 + } + } /// /// 清除所有缓存,在模型变化时调用 diff --git a/src/Core/Spatial/SpatialIndexManager.cs b/src/Core/Spatial/SpatialIndexManager.cs index 135cc7f..8a3f8fc 100644 --- a/src/Core/Spatial/SpatialIndexManager.cs +++ b/src/Core/Spatial/SpatialIndexManager.cs @@ -86,12 +86,19 @@ namespace NavisworksTransport.Core.Spatial ClashIntegration.Instance.BuildChannelObjectsCache(); ClashIntegration.BuildAllGeometryItemsCache(); - // 1. 获取所有几何对象 - var allItems = Application.ActiveDocument.Models.RootItemDescendantsAndSelf - .Where(item => item.HasGeometry) - .ToList(); + // 1. 从缓存获取所有几何对象(避免重复遍历) + var allItems = ClashIntegration.GetAllGeometryItemsCache(); - LogManager.Info($"[空间索引] 找到 {allItems.Count} 个几何对象(含通道)"); + if (allItems == null) + { + // 缓存不存在,手动获取(不应该发生) + LogManager.Warning("[空间索引] 几何对象缓存不存在,回退到实时获取"); + allItems = Application.ActiveDocument.Models.RootItemDescendantsAndSelf + .Where(item => item.HasGeometry) + .ToList(); + } + + LogManager.Info($"[空间索引] 从缓存获取 {allItems.Count} 个几何对象(含通道)"); if (allItems.Count == 0) {