Posted on 7. March 2009

Revit 2010 API Performance

As Matt has said the Revit 2010 API release is impressive. From a feature perspective the Family creation and editing API are a standout for me. Well designed, they largely mirror what you can do in Revit as a user.

However, what I feel is probably the standout feature of the last year and the 2010 release season is the new openness we’re seeing from the Factory. I’ve longed argued the features that make Revit unique are the very features that make the software engineering of new features in Revit so difficult and resource intensive. Particularly compared to ‘dumb’ 2D cad. So it’s fantastic to see them sharing their experiences and trying to explain the rational for some of the design decisions.Whether it’s the new blog, the talk at AU or the new building to me they’re all signs the future of Revit is exciting and in good hands.

Now, this isn’t a Revit love fest and I don’t have shares in Autodesk ;-) Those that know me , know I’ve given the Factory a hard time about API performance in the past. Pre the Revit 2009 release, API performance on any normal sized commercial project (100-300Mb) was a bit of a joke. The 2009 release radically improved API performance with the introduction of Filters. Subscribing to API events are now a realistic possibility when designing Revit API commands. And the new events in the 2010 release are a further huge improvement. Opening up a number of possible design approaches not possible before.

Regarding API performance, I’m always eager to see what has improved if anything. So with the impending release of Revit 2010 and near RTM releases on the Beta site, I’ve done a little test on one of my standard test projects (~100Mb) to gauge any improvement in API performance. It’s only a simple test,this is the code and I ran it against the same project in 2009 and upgraded to 2010.

var rApp = commandData.Application;
var rDoc = rApp.ActiveDocument;
Stopwatch sw = Stopwatch.StartNew();
var wallFilter = rApp.Create.Filter.NewCategoryFilter(BuiltInCategory.OST_Walls);
var doorsFilter = rApp.Create.Filter.NewCategoryFilter(BuiltInCategory.OST_Doors);
var wallsDoors = rApp.Create.Filter.NewLogicOrFilter(wallFilter, doorsFilter);
var itor = rDoc.get_Elements(wallsDoors);
sw.Stop();
Debug.WriteLine(string.Format("R2010 iterator creation time {0}ms", sw.ElapsedMilliseconds));
sw.Reset();
sw.Start();
int wallCount = 0;
int doorCount = 0;
int totalCount = 0;
while(itor.MoveNext())
{
    Element current = itor.Current as Autodesk.Revit.Element;
    if (current is Autodesk.Revit.Elements.Wall) wallCount++;
    else if (current is Autodesk.Revit.Elements.FamilyInstance) doorCount++;
    totalCount++;
}
sw.Stop();
Debug.WriteLine(string.Format("R2010 Total elements : {0}, wall count : {1}, door count : {2}, in {3}ms", totalCount, wallCount, doorCount, sw.ElapsedMilliseconds));

As you can see it gets the number of walls and doors in the project and calculates in milliseconds the time to build the filter and get the elements. And these are the results:

R2009

R2009 iterator creation time 3ms

R2009 Total elements : 2365, wall count : 1816, door count : 391, in 27834ms

R2009 Total elements : 2365, wall count : 1816, door count : 391, in 1986ms

R2009 Total elements : 2365, wall count : 1816, door count : 391, in 1978ms

R2009 Total elements : 2365, wall count : 1816, door count : 391, in 1963ms

R2009 Total elements : 2365, wall count : 1816, door count : 391, in 1956ms

R2010

R2010 iterator creation time 30ms

R2010 Total elements : 2319, wall count : 1754, door count : 404, in 2999ms 928% improvement

R2010 Total elements : 2319, wall count : 1754, door count : 404, in 1275ms

R2010 Total elements : 2319, wall count : 1754, door count : 404, in 1266ms

R2010 Total elements : 2319, wall count : 1754, door count : 404, in 1270ms

R2010 Total elements : 2319, wall count : 1754, door count : 404, in 1265ms (avg over 4 runs 55% improvement)

So… YEEE HAH!!! Yep, 55% improvement in performance with a 928% improvement for the first iteration compared with Revit 2009. The improvement  for the 1st iteration is interesting.  I always assumed the degradation in performance was related to some object marshalling issue between the managed world of the API and the unmanaged world that is the host Revit application. Maybe not?

On large projects the first time a command was run it could take well over a minute. The fact the first iteration is now only 2-3 times as slow as subsequent iterations eliminates this usability issue that came up with customers and Revit 2009 commands.

In conclusion, another fantastic improvement in API performance from the Factory.

Comments

Comments are closed