Plugin languages comparison
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Dear fellow developers,
While I was learning some programming techniques I heard somewhere that C++ is the fastest language out there, so I decided to do a test to see which of the three languages you can use to write a Revit plugin is the fastest. During my test it occurred to me that, because the Revit API is managed, the C++ implementation you can use to write a Revit plugin is considerably slower than native C++.
My test was to create 1000 modelcurves in Revit, the result are as follows:
With visual C++ it took 4 seconds, 733 milliseconds and 9619 ticks,
With C# it took 7 seconds, 989 milliseconds and 4320 ticks,
With VB.NET it took 5 seconds, 16 milliseconds and 3316 ticks.
The code for each of the three plugins is as follows:
Visual C++:
-Header:
#pragma once
using namespace System;
namespace HelloRevitCpp {
[Autodesk::Revit::Attributes::TransactionAttribute(
Autodesk::Revit::Attributes::TransactionMode::Manual)]
[Autodesk::Revit::Attributes::RegenerationAttribute(
Autodesk::Revit::Attributes::RegenerationOption::Manual)]
public ref class Command
: Autodesk::Revit::UI::IExternalCommand
{
public:
virtual Autodesk::Revit::UI::Result Execute(
Autodesk::Revit::UI::ExternalCommandData^ commandData,
System::String^% message,
Autodesk::Revit::DB::ElementSet^ elements);
};
}
-Main code:
#include "HelloRevitCpp.h"
using namespace Autodesk::Revit::DB;
using namespace Autodesk::Revit::UI;
using namespace HelloRevitCpp;
Result Command::Execute(ExternalCommandData^ commandData, String^% message, ElementSet^ elements) {
Diagnostics::Stopwatch^ watch = gcnew Diagnostics::Stopwatch();
watch->Start();
Document^ doc = commandData->Application->ActiveUIDocument->Document;
Plane^ plane = Plane::CreateByNormalAndOrigin(gcnew XYZ(0, 0, 1), gcnew XYZ());
Transaction trans(doc);
trans.Start("Test");
SketchPlane^ sketchPlane = SketchPlane::Create(doc, plane);
for (int i{ 0 }; i < 1000; ++i) {
doc->Create->NewModelCurve(Line::CreateBound(gcnew XYZ(), gcnew XYZ(i + 1, 0, 0)), sketchPlane);
}
trans.Commit();
watch->Stop();
TaskDialog testDialog("Test");
testDialog.Show("Test", "It took " + watch->Elapsed.Seconds + " seconds, " + watch->Elapsed.Milliseconds + " milliseconds and " + watch->Elapsed.Ticks + " ticks to create 1000 modelcurve");
return Result::Succeeded;
}
C#:
using System.Diagnostics;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
namespace HelloRevitCS
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Document doc = commandData.Application.ActiveUIDocument.Document;
Plane plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, new XYZ());
Transaction trans = new Transaction(doc);
trans.Start("Test");
SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
for (int i = 0; i < 1000; ++i)
{
doc.Create.NewModelCurve(Line.CreateBound(new XYZ(), new XYZ(i + 1, 0, 0)), sketchPlane);
}
trans.Commit();
watch.Stop();
TaskDialog.Show("Test", "It took " + watch.Elapsed.Seconds + " seconds, " + watch.Elapsed.Milliseconds + " milliseconds and " + watch.Elapsed.Ticks + " ticks to create 1000 modelcurves");
return Result.Succeeded;
}
}
}
VB.NET:
Imports Autodesk.Revit.Attributes
Imports Autodesk.Revit.UI
Imports Autodesk.Revit.DB
<Transaction(TransactionMode.Manual)>
Public Class Command
Implements IExternalCommand
Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute
Dim watch As Stopwatch = New Stopwatch
watch.Start()
Dim doc As Document = commandData.Application.ActiveUIDocument.Document
Dim plane As Plane = plane.CreateByNormalAndOrigin(XYZ.BasisZ, New XYZ())
Dim trans As Transaction = New Transaction(doc)
trans.Start("Test")
Dim sketchPlane As SketchPlane = SketchPlane.Create(doc, plane)
For i = 1 To 1000
doc.Create.NewModelCurve(Line.CreateBound(New XYZ(), New XYZ() + XYZ.BasisY.Multiply(i)), sketchPlane)
Next
trans.Commit()
watch.Stop()
TaskDialog.Show("Runtimetest", "It took " & watch.Elapsed.Seconds & " seconds, " & watch.Elapsed.Milliseconds & " milliseconds and " & watch.Elapsed.Ticks & " ticks to create 1000 modelcurves")
Return Result.Succeeded
End Function
End Class