GuyR
2008-06-15, 09:59 PM
There have been comments about 2009 API performance in a few posts. Last week ADN published a note recommending an approach for categories that frankly got it wrong from my reasonably extensive testing on real world projects. So without giving away all my tricks ;-) here is a summary of what to/not to do if you are interested in giving you users the best performance experience available.
1.. If the logic fits the command, have the user select elements in the active view and process these instead of walking the entire project. This will be significantly faster than any other method.
2.. Unless there is an element you can't get via a combination of Filters never walk the tree using Document.Elements. In other words avoid at all costs this code (c#):
ElementIterator itor = commandData.Application.ActiveDocument.Elements;
while(itor.MoveNext())
{
Element element = itor.Current as Element;
}
Unfortunately , new users will look to the SDK which in most cases still use this approach.
3.. Understand and use Filters exclusively where possible. The performance gains particularly on subsequent running of the command during a session will yield a massive improvement in performance. Not all filter options will give the same % increase in performance and some don't perform as expected. Test against real world projects not blank projects. To understand what you can do, start with the filter sample included in the SDK. Then move on to writing simple test commands to evaluate different filter combinations and the resulting performance gains.
4.. If you are writing localised commands the approach has been to get a language neutral category and test an element against this . However Filters make this redundant which is a good thing because. Never have the following line of code execute every time a command is run.
ElementId category = commandData.Application.ActiveDocument.Settings.Categories.get_Item(Autodesk.Revit.BuiltInCategory.OST_Doors).Id;
This single line walks the whole element tree building a unique set of categories. So in one line you can at a minimum double the time a command would take to run. If you have to get a category do it once and persist the id somewhere either per session or across sessions.
Cheers,
Guy
1.. If the logic fits the command, have the user select elements in the active view and process these instead of walking the entire project. This will be significantly faster than any other method.
2.. Unless there is an element you can't get via a combination of Filters never walk the tree using Document.Elements. In other words avoid at all costs this code (c#):
ElementIterator itor = commandData.Application.ActiveDocument.Elements;
while(itor.MoveNext())
{
Element element = itor.Current as Element;
}
Unfortunately , new users will look to the SDK which in most cases still use this approach.
3.. Understand and use Filters exclusively where possible. The performance gains particularly on subsequent running of the command during a session will yield a massive improvement in performance. Not all filter options will give the same % increase in performance and some don't perform as expected. Test against real world projects not blank projects. To understand what you can do, start with the filter sample included in the SDK. Then move on to writing simple test commands to evaluate different filter combinations and the resulting performance gains.
4.. If you are writing localised commands the approach has been to get a language neutral category and test an element against this . However Filters make this redundant which is a good thing because. Never have the following line of code execute every time a command is run.
ElementId category = commandData.Application.ActiveDocument.Settings.Categories.get_Item(Autodesk.Revit.BuiltInCategory.OST_Doors).Id;
This single line walks the whole element tree building a unique set of categories. So in one line you can at a minimum double the time a command would take to run. If you have to get a category do it once and persist the id somewhere either per session or across sessions.
Cheers,
Guy