8.2 KiB
8.2 KiB
轻量化智能遍历预览实施方案
目标
实现基于属性的智能遍历算法,替代现有的固定深度收集方式,专注于预览性能提升。保存逻辑暂时不修改。
核心修改点
1. 新增智能遍历算法(SimplifiedModelSplitterManager.cs)
PreviewSplitWithSmartTraversal方法:
private List<SplitPreviewResult> PreviewSplitWithSmartTraversal(
SplitConfiguration config, IGroupingStrategy strategy)
{
var results = new List<SplitPreviewResult>();
foreach (Model model in document.Models)
{
foreach (ModelItem rootChild in model.RootItem.Children)
{
TraverseAndRecord(rootChild, strategy, config, results, 1);
}
}
return results;
}
TraverseAndRecord递归方法:
private void TraverseAndRecord(ModelItem node, IGroupingStrategy strategy,
SplitConfiguration config, List<SplitPreviewResult> results, int currentDepth)
{
// 检查当前节点的分层属性
string layerValue = strategy.ExtractAttributeValue(node);
if (!string.IsNullOrEmpty(layerValue))
{
// 找到分层属性,创建预览结果,停止该分支遍历
var layerResult = CreateLightweightLayerResult(layerValue, node, strategy.GroupTypeName);
results.Add(layerResult);
return; // 关键:停止遍历该分支
}
// 未找到分层属性且未达深度限制,继续遍历子节点
if (currentDepth < config.MaxDepth && node.Children != null)
{
foreach (ModelItem child in node.Children)
{
TraverseAndRecord(child, strategy, config, results, currentDepth + 1);
}
}
}
2. 最简化预览结果创建
CreateLightweightLayerResult方法:
private SplitPreviewResult CreateLightweightLayerResult(string layerValue, ModelItem rootNode, string groupTypeName)
{
return new SplitPreviewResult
{
LayerName = SanitizeLayerName(layerValue),
Items = new ModelItemCollection { rootNode },
Metadata = new Dictionary<string, object>
{
["LayerValue"] = layerValue,
["RootNodeReference"] = rootNode,
["GroupType"] = groupTypeName
}
};
}
说明:
- 不设置 ItemCount、EstimatedFileSize、Status 等字段
- 只包含预览必需的信息:LayerName、根节点引用、元数据
- 避免任何不必要的计算和统计
3. 策略接口扩展
IGroupingStrategy接口新增方法:
public interface IGroupingStrategy
{
string GroupTypeName { get; }
// 现有方法保持不变
Dictionary<string, GroupItem> GroupItems(ModelItemCollection items, SplitConfiguration config);
// 新增:单节点属性检测
string ExtractAttributeValue(ModelItem node);
}
4. 示例策略类升级
FloorAttributeStrategy新增实现:
public string ExtractAttributeValue(ModelItem node)
{
// 优先在"分层信息"类别中查找楼层属性
return GetAttributeFromCategory(node, "分层信息", "楼层") ??
GetAttributeFromCategory(node, "Identity Data", "Floor") ??
GetAttributeFromCategory(node, "Constraints", "Level");
}
private string GetAttributeFromCategory(ModelItem node, string categoryName, string attributeName)
{
try
{
foreach (PropertyCategory category in node.PropertyCategories)
{
if (category.DisplayName == categoryName)
{
foreach (DataProperty property in category.Properties)
{
if (property.DisplayName == attributeName)
{
return property.Value.ToDisplayString();
}
}
}
}
}
catch (Exception ex)
{
LogManager.Warning($"获取属性失败: {ex.Message}");
}
return null;
}
5. 主入口方法修改
PreviewSplit方法调整:
public List<SplitPreviewResult> PreviewSplit(SplitConfiguration config)
{
try
{
// 缓存检查等现有逻辑保持不变...
var strategy = CreateStrategy(config.Strategy);
// 使用新的智能遍历,完全替代GetItemsByDepthUnified
LogManager.Info($"开始智能遍历分层预览,策略: {config.Strategy},深度限制: {config.MaxDepth}");
var previewResults = PreviewSplitWithSmartTraversal(config, strategy);
LogManager.Info($"智能遍历完成,识别到 {previewResults.Count} 个分层");
// 缓存和状态更新等现有逻辑保持不变...
return previewResults;
}
catch (Exception ex)
{
LogManager.Error($"智能遍历预览失败: {ex.Message}", ex);
throw;
}
}
性能优势
避免的性能瓶颈
- 不再调用GetItemsByDepthUnified():避免收集所有深度内的节点
- 不进行子节点收集:预览时只保存根节点引用
- 不计算统计信息:ItemCount、EstimatedFileSize、Status全部跳过
- 智能分支停止:找到分层属性立即停止该分支遍历
预期性能提升
- 内存占用大幅降低:从数万节点减少到只有分层根节点
- 响应速度显著提升:预览结果近乎实时生成
- CPU使用率降低:避免大量不必要的节点遍历和属性检查
算法逻辑对比
原有算法(性能瓶颈)
1. 收集所有指定深度内的节点(GetItemsByDepthUnified)
└── 可能收集数万个节点到内存
2. 遍历所有节点检查属性(GroupItems)
└── 对每个节点都进行属性查找
3. 统计每个分组的节点数量和文件大小
└── 额外的计算开销
新算法(智能优化)
1. 从根节点开始递归遍历
├── 检查当前节点属性
├── 找到分层属性 → 停止该分支,记录结果
└── 未找到 → 继续遍历子节点(受深度限制)
2. 只保存分层根节点引用
└── 最小内存占用
3. 跳过所有统计计算
└── 零额外开销
实施步骤
- 第一步:在SimplifiedModelSplitterManager中实现智能遍历算法
- 第二步:扩展IGroupingStrategy接口,添加ExtractAttributeValue方法
- 第三步:升级FloorAttributeStrategy实现ExtractAttributeValue
- 第四步:修改PreviewSplit方法使用新算法
- 第五步:测试验证楼层分层的智能预览效果
- 第六步:逐步升级其他策略类(ZoneAttributeStrategy、SubSystemAttributeStrategy等)
兼容性保证
- 保留现有方法:所有原有方法和属性完全保持不变
- 保存逻辑不变:当前的ExecuteSplitAsync等保存方法完全不修改
- 可回滚设计:如有问题可轻松恢复到原有实现
扩展性考虑
其他策略类升级
按照相同模式升级其他策略类:
- ZoneAttributeStrategy: 在"分层信息"中查找"分区"属性
- SubSystemAttributeStrategy: 在"分层信息"中查找"子系统"属性
- FloorDetectionStrategy: 实现智能楼层检测逻辑
自定义属性支持
为用户自定义分层属性预留接口:
public class CustomAttributeStrategy : IGroupingStrategy
{
private string _targetAttribute;
private string _targetCategory;
public string ExtractAttributeValue(ModelItem node)
{
return GetAttributeFromCategory(node, _targetCategory, _targetAttribute);
}
}
测试验证计划
性能测试
- 对比测试:新旧算法在相同模型上的性能表现
- 内存监控:预览过程中的内存使用情况
- 响应时间:从触发预览到显示结果的时间
功能测试
- 分层准确性:确保智能遍历找到的分层与预期一致
- 深度控制:验证遍历深度限制正常工作
- 边界情况:测试无分层属性、深度为0等特殊情况
预期收益
此方案专注于预览性能优化,预计将带来:
- 90%以上的内存使用量减少
- 80%以上的预览响应时间提升
- 完全兼容现有功能,风险极低
- 为后续智能检测功能奠定基础
通过这次重构,分层预览将从当前的性能瓶颈转变为系统的性能优势点。