Write performance benchmarks for your Revit add-ins using the BenchmarkDotNet, and share reproducible measurement experiments.
You can install this library as a NuGet package.
The packages are compiled for specific versions of Revit. To support different versions of libraries in one project, use the RevitVersion property:
<PackageReference Include="Nice3point.BenchmarkDotNet.Revit" Version="$(RevitVersion).*"/>Start by creating a new class inheriting from RevitApiBenchmark:
public class MyBenchmarks : RevitApiBenchmark
{
}Add one or more methods marked with [Benchmark]:
using BenchmarkDotNet.Attributes;
public class MyBenchmarks : RevitApiBenchmark
{
[Benchmark]
public void MyBenchmark()
{
}
}This is your runnable benchmark. The base class ensures the benchmark executes within Revit's single-threaded API context.
You can run your benchmarks with a simple configuration.
BenchmarkDotNet uses the Release configuration by default to run, which will cause a failure when running benchmarks for Revit, where API multi-versioning is required.
In this case, use the WithCurrentConfiguration() extension for the Job, which will run the benchmark for your selected Solution configuration.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using Nice3point.BenchmarkDotNet.Revit;
var configuration = ManualConfig.Create()
.AddJob(Job.Default.WithCurrentConfiguration());
BenchmarkRunner.Run<MyBenchmarks>(configuration);Important
You must have a licensed copy of Autodesk Revit installed on your machine to run benchmarks, with a version that matches the selected Solution configuration.
Benchmark Revit application-level operations:
using BenchmarkDotNet.Attributes;
public class RevitApplicationBenchmarks : RevitApiBenchmark
{
[Benchmark]
public XYZ NewXyz()
{
return new XYZ(3, 4, 5);
}
[Benchmark]
public XYZ CreateNewXyz()
{
return Application.Create.NewXYZ(3, 4, 5);
}
}Use OnGlobalSetup and OnGlobalCleanup overrides to open and close a document around benchmark iterations.
BenchmarkDotNet provides [GlobalSetup] and [GlobalCleanup] hooks, but due to library limitations, they cannot be assigned twice:
using BenchmarkDotNet.Attributes;
public class RevitCollectorBenchmarks : RevitApiBenchmark
{
private Document _document = null!;
protected sealed override void OnGlobalSetup()
{
_document = Application.NewProjectDocument(UnitSystem.Metric);
}
protected sealed override void OnGlobalCleanup()
{
_document.Close(false);
}
[Benchmark]
public IList<Element> WhereElementIsNotElementTypeToElements()
{
return new FilteredElementCollector(_document)
.WhereElementIsNotElementType()
.ToElements();
}
[Benchmark]
public List<Element> WhereElementIsNotElementTypeToList()
{
return new FilteredElementCollector(_document)
.WhereElementIsNotElementType()
.ToList();
}
}
BenchmarkDotNet v0.15.8, Windows 11 (10.0.22631.6199/23H2/2023Update/SunValley3)
AMD Ryzen 5 5600 3.50GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.100
[Host] : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
MediumRun : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
Job=MediumRun BuildConfiguration=Release.R26 IterationCount=15
LaunchCount=2 WarmupCount=10
| Method | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|
| WhereElementIsNotElementTypeToElements | 2.203 ms | 0.0494 ms | 0.1440 ms | 295.05 KB |
| WhereElementIsNotElementTypeToList | 2.190 ms | 0.0436 ms | 0.0929 ms | 310.09 KB |
BenchmarkDotNet initializes Revit with the English - United States language and the C:\Program Files\Autodesk\Revit {version} installation path. To override these defaults:
-
Add the assembly-level attribute to any .cs file in your project (e.g., Program.cs):
using Nice3point.Revit.Injector.Attributes; [assembly: RevitLanguage("ENU")] [assembly: RevitInstallationPath("D:\Autodesk\Revit Preview")]
-
Or add the attributes directly to your .csproj file:
<!-- Revit Environment Configuration --> <ItemGroup> <AssemblyAttribute Include="Nice3point.Revit.Injector.Attributes.RevitLanguageAttribute"> <_Parameter1>ENU</_Parameter1> </AssemblyAttribute> <AssemblyAttribute Include="Nice3point.Revit.Injector.Attributes.RevitInstallationPathAttribute"> <_Parameter1>D:\Autodesk\Revit $(RevitVersion)</_Parameter1> </AssemblyAttribute> </ItemGroup>
The RevitLanguage attribute accepts a language name (e.g., "English - United States"), code (e.g., "ENU")
or LanguageType enum value (e.g., "English_GB" or "15").