Jeremy Tammik

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

« Relationship Inverter | Main | AU 2008 »

October 03, 2008

Filter Performance

This post is entirely thanks to Guy Robinson, who has always been the quickest to test and comment on performance issues in the Revit API, in response to the previous post. He says:

Like you, I initially thought the TypeFilter was a more elegant filter for FamilyInstances etc., but having done a lot of testing I now have my suspicions regarding how filters work internally and why it's not necessarily a good filter option for certain element types.

In the relationship code for this situation, it is significantly faster to just use the category filter as demonstrated in the command below. On a 100 MB project, I compared the times required to retrieve 571 elements using the type filter as shown in the previous post versus using an anonymous method to filter away objects of the wrong type after receiving them from Revit. These are the execution times for running the two commands a repeated number of times:

using TypeFilter:
Time to get 571 elements 37226
Time to get 571 elements  6042
Time to get 571 elements  6024
Time to get 571 elements  6172

using anonymous method:
Time to get 571 elements 33769
Time to get 571 elements  2052
Time to get 571 elements  2050
Time to get 571 elements  2048
Time to get 571 elements  2034
Time to get 571 elements  2037

As you can see, using the anonymous method is three times as fast. So while filters are fantastic, they're not always the best solution ;-)

So much for the comment from Guy, whom I would like to thank very much for this invaluable input. Here is the alternative code he is describing, using an anonymous method instead of the TypeFilter:

class CmdFilterPerformance : IExternalCommand
{
  public CmdResult Execute(
    ExternalCommandData commandData,
    ref string message,
    ElementSet elements )
  {
    try
    {
      Application app = commandData.Application;
      Document doc = app.ActiveDocument;
 
      Stopwatch sw = Stopwatch.StartNew();
 
      // f5 = f1 && f4 
      //    = f1 && (f2 || f3) 
      //    = family instance and (door or window)
 
      Autodesk.Revit.Creation.Filter cf
        = app.Create.Filter;
 
      //Filter f1 = cf.NewTypeFilter( 
      //  typeof( FamilyInstance ) );
 
      Filter f2 = cf.NewCategoryFilter(
        BuiltInCategory.OST_Doors );
      Filter f3 = cf.NewCategoryFilter(
        BuiltInCategory.OST_Windows );
 
      Filter f4 = cf.NewLogicOrFilter( f2, f3 );
      //Filter f5 = cf.NewLogicAndFilter( f1, f4 );
 
      //int n = doc.get_Elements( f5, openings );
 
      List<Element> openings = new List<Element>();
      doc.get_Elements( f4, openings );
 
      List<Element> openingInstances
        = openings.FindAll( delegate( Element element )
          {
            return !( element is Symbol );
          } );
      int n = openingInstances.Count;
 
      sw.Stop();
 
      Debug.WriteLine( string.Format(
        "Time to get {0} elements {1}",
        n, sw.ElapsedMilliseconds ) );
 
      return CmdResult.Succeeded;
    }
    catch( Exception ex )
    {
      message = ex.Message + ex.StackTrace;
      return CmdResult.Failed;
    }
  }
}

It really goes to show how extremely important testing on real life projects and scrupulous profiling and benchmarking is to ensure that you as a professional developer really deliver optimal quality to your clients. It also shows how easy it is for me to play around in an ivory tower and that my messages should always be taken with large grains of salt. And everybody else's too, of course. Guy has already pointed out some performance traps when blindly trusting Revit API filters to be fast in the past ... this one really brings the message across!

I am adding the complete Visual Studio solution here. This version 1.0.0.4 includes the four commands we discussed so far: CmdListWalls, CmdRelationshipInverter, CmdWallDimensions and the new CmdFilterPerformance.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00e553e16897883301053513e133970b

Listed below are links to weblogs that reference Filter Performance:

Comments

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

RSS Feed

Search

Search