perf: 空间索引复用几何对象缓存避免重复遍历
问题描述: - 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 <noreply@anthropic.com>
This commit is contained in:
parent
2c6187a674
commit
320dfa23f3
@ -1186,9 +1186,6 @@ namespace NavisworksTransport
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构建几何对象列表缓存,一次性获取所有几何对象
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 构建几何对象列表缓存,一次性获取所有几何对象
|
||||
/// </summary>
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取几何对象缓存(供外部使用)
|
||||
/// </summary>
|
||||
/// <returns>几何对象列表的副本,如果缓存不存在则返回null</returns>
|
||||
public static List<ModelItem> GetAllGeometryItemsCache()
|
||||
{
|
||||
lock (_cacheLock)
|
||||
{
|
||||
return _allGeometryItemsCache?.ToList(); // 返回副本以保证线程安全
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有缓存,在模型变化时调用
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user