Thursday, February 28, 2008

Revit 2009 API: Searching Improves

One of the areas which is nice to see Autodesk's continuing investments in is Searching within a Revit model.

Searching is a fundamental activity - almost every Revit application that exists, whether it's just to look up a symbol or whether it's a full-blown analysis application needs to scan the model looking for specific elements.

There were already a few different methods of searching within the model - GuyR and I had a spirited discussion about them recently on the AUGI board.... and Guy developed a test application to perform a speed test of the three ways...

The test involves scanning an aribitary Revit model looking for either Walls or Walls and Rooms, using all the different methods available.

In Revit 2008, these were the results:

Case 1Case 2

  • Bad: Iterating through each element - testing for the category to match
  • Better: Testing the .NET Type of each element, looking for the right ones.

  • MyBest: (Guy's Best): The same as better - but don't even cast down to a Revit Element to save some cycles.

  • ElementFilterIterator: Use the get_Elements( type ) method to get all the elements in one call.

While I have historically preferred the ElementFilterIterator approach, Guy's method is faster - particularly if you're looking for more than one type. If you are looking for more than one type (as shown in case #2 - in Guy's method you only have to iterate through once - whereas ElementFilterIterator is almost twice as slow). ElementFilterIterator also has another quirk - it does not handle subclass types - so if you ask for "View", you're not going to get "View3D" or "ViewSheet"...

Important Note: As a side note on a pure "Category" approach - remember that asking for Walls will give you both "Walls" and "Wall Styles"... So I think it's likely that you'll almost always need to screen by "Type", not just by "Category".

2009 Rolls in...

So when 2009 came across my desk, I was curious to see what had changed. Autodesk had promised some performance enhancements to searching - what form would they take? I modified Guy's application to support the two new searching mechanisms - and I figured that we'd re-test the others, because it was said that they could improve as well.

The new Filtering mechanisms

Revit 2009 introduces the concept of "filters" which can be used to define the criteria for finding elements - this includes searching by:

  • Category
  • Type
  • Family
  • InstanceUsage
  • Material
  • Parameter Value
  • Structural Type
  • Symbol
  • Wall Usage

What's more, you can combine filters using the LogicAND, LogicNOT, and LogicOR filters. So you could, with one call, look for Doors made of a particular material (OK, Material is a tricky one - perhaps that's a bad example).

What does it look like?

// get the categories

Category _wallCat = _doc.Settings.Categories.get_Item( BuiltInCategory.OST_Walls );
Category _roomCat = _doc.Settings.Categories.get_Item( BuiltInCategory.OST_Rooms );

//make the filter
CategoryFilter wallFilter = _app.Create.Filter.NewCategoryFilter(_wallCat);
CategoryFilter roomFilter = _app.Create.Filter.NewCategoryFilter(_roomCat);

// put the filters together
Filter myFilter =
_app.Create.Filter.NewLogicOrFilter(wallFilter, roomFilter);

ElementIterator esi = _document.get_Elements(myFilter);

So how did things turn out in 2009?

Case 1Case 2

So what has changed?

Strangely - Guy's best approach consistently comes up slightly slower than his "better" approach - that I can't explain. The ElementFilterIterator approach performs about the same - even though it has been significantly changed - it now uses an ElementIterator instead, and it supports SubTypes.

The most interesting changes are for the new mechanisms - Filter Criteria based searching. While we didn't explore all of them - we can see that:

  • Type-based searching was roughtly the same as the ElementFilterIterator approach

  • The Category search absolutely SMOKED everything else - particularly when looking for two categorys (walls and rooms).


All in all, there are some mechanism that are still fast - but if performance is a concern, you'll definitely want to check out the new Filter approach to getting elements.

I'll try to post the updated sourcecode for this shortly so that you can try it out for yourself.


Your mileage may vary. There seemed to be a great deal of variations in the runs each time they were run.

1 comment:

Rod said...

Great news, very interesting to see furthered results of our discussion!

Good work