原文链接:
ToElementIds Performance
从 Revit FilteredElementCollector 到包含 Element 或是 ElementId 的显示的 .NET 集合对象的转换通常是开销相当大的,所以应该被极力避免。
以下是一段在 Revit API 开发团队和第三方开发者之间的对话:
问题
我有时候会使用 ToElementIds() 方法
我想知道为什么 ToElementIds() 方法会导致这么明显的性能降低。按照我的理解,这两段代码的功能和性能都应该是一样的。如果 ToElementIds() 确实会导致性能降低,那么我们应该在什么情况下使用它呢?
回答
你的测试结果并不让人意外。ToElementIds() 和 ToElements() 会创建一个新的 .NET 集合对象来包含所有 FilteredElementCollector 对象中的元素,然后将这个新创建的集合对象返回给你。这个过程实际上是将一个本地的集合对象转换成给一个托管的集合对象。显然,这种转换是需要开销的。
适合使用 ToElementIds() 或者 ToElements() 的场景如下:
1. 需要在内存中维护一个具体的元素集合
2. 或者你需要 .NET 集合对象作为某些 Revit API 方法的参数
例如:Delete()
如果只是想遍历元素,那么直接使用 FilterElementCollector 对象是最好的选择。
从 Revit FilteredElementCollector 到包含 Element 或是 ElementId 的显示的 .NET 集合对象的转换通常是开销相当大的,所以应该被极力避免。
我最近已经讨论过多种对元素检索操作的优化,详见博文:FindElement and collector optimisations
以下是一段在 Revit API 开发团队和第三方开发者之间的对话:
问题
我有时候会使用 ToElementIds() 方法
var fc = new FilteredElementCollector( doc )
.OfSomething()
.ToElementIds();
foreach( var elemId in fc )
{
var element = doc.GetElement( elemId );
}
我发现上面这种元素访问方式所需的时间要比直接访问 FilterElementCollector 对象慢 25%
var fc = new FilteredElementCollector( doc )
.OfSomething();
foreach (var elem in fc)
{
var element = elem;
}
我想知道为什么 ToElementIds() 方法会导致这么明显的性能降低。按照我的理解,这两段代码的功能和性能都应该是一样的。如果 ToElementIds() 确实会导致性能降低,那么我们应该在什么情况下使用它呢?
回答
你的测试结果并不让人意外。ToElementIds() 和 ToElements() 会创建一个新的 .NET 集合对象来包含所有 FilteredElementCollector 对象中的元素,然后将这个新创建的集合对象返回给你。这个过程实际上是将一个本地的集合对象转换成给一个托管的集合对象。显然,这种转换是需要开销的。
适合使用 ToElementIds() 或者 ToElements() 的场景如下:
1. 需要在内存中维护一个具体的元素集合
2. 或者你需要 .NET 集合对象作为某些 Revit API 方法的参数
例如:Delete()
如果只是想遍历元素,那么直接使用 FilterElementCollector 对象是最好的选择。