As demonstrated previously, the ObjectId.Open approach takes more time than it looks like. After all objects are closed and/or disposed and even the related test command is returned, AutoCAD will still be busy for quite a while (in the best case still around the same amount of time as those Open and Close calls take) with no responses to any input.
On the other hand, the Transaction approach does not have delays. After the transaction is committed, (all opened objects being closed) and the command returns, AutoCAD will respond to input right away.
In this article, we use the same simple but cool and easy-to-use AutoCAD Performance Meter as introduced a bit earlier to measure the real performance of the Transaction.GetObject calls.
Here is the performance meter class for convenience again.
public class AcadPerformanceMeter
{
private System.Diagnostics.Stopwatch mWatch;
private Autodesk.AutoCAD.EditorInput.Editor mEditor;
private string mTesterName;
private double mNominalTotalTime;
private double mRealTotalTime;
private double mCodeEndTotalTime = -1;
public AcadPerformanceMeter(Autodesk.AutoCAD.EditorInput.Editor ed, string testerName)
{
mTesterName = testerName;
mWatch = new Stopwatch();
mWatch.Start();
mEditor = ed;
mEditor.EnteringQuiescentState += EditorEvent_EnteringQuiescentState;
mEditor.Document.CommandEnded += Document_CommandEnded;
}
public void CodeEnd()
{
mCodeEndTotalTime = mWatch.Elapsed.TotalMilliseconds;
}
private void Document_CommandEnded(object sender, CommandEventArgs e)
{
mNominalTotalTime = mWatch.Elapsed.TotalMilliseconds;
mEditor.Document.CommandEnded -= Document_CommandEnded;
}
private void EditorEvent_EnteringQuiescentState(object sender, EventArgs e)
{
mWatch.Stop();
mRealTotalTime = mWatch.Elapsed.TotalMilliseconds;
mEditor.WriteMessage("{0} in ms. CodeEnd:{1} CmdEnd:{2} RealEnd:{3}\n", mTesterName,mCodeEndTotalTime, mNominalTotalTime, mRealTotalTime);
mEditor.EnteringQuiescentState -= EditorEvent_EnteringQuiescentState;
}
}
Here is the test command to meansure both nominal and real performance of the Transaction.GetObject calls.
[CommandMethod("RealPerformanceMeterOfTransactionGetObject")]
public static void RealPerformanceOfTransactionGetObject_Method()
{
Database db = HostApplicationServices.WorkingDatabase;
try
{
AcadPerformanceMeter realTimer = new AcadPerformanceMeter(MgdAcApplication.DocumentManager.MdiActiveDocument.Editor, "Transaction");
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
foreach (ObjectId id in btr)
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
ent.ColorIndex = 44;
}
tr.Commit();
}
realTimer.CodeEnd();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
To avoid impact of each other test as much as possible, we kept only one drawing open at a time. Four drawings were used to make the tests and they contained 5000, 15000, 30000, and 60000 entities respectively. Here are the outputs of the series of tests against the four drawings.
Transaction in ms. CodeEnd:170.1368 CmdEnd:170.3738 RealEnd:170.5875
Transaction in ms. CodeEnd:2855.5433 CmdEnd:2855.7831 RealEnd:2856.1732
Transaction in ms. CodeEnd:16802.5489 CmdEnd:16802.7869 RealEnd:16803.3212
Transaction in ms. CodeEnd:68969.1139 CmdEnd:68969.3528 RealEnd:68970.2748
As can be seen, all the three ends of the Transaction.GetObject calls happen at almost the same time. Here is a table that has the code/command end (nominal) performance, real performance, delay and percentage put together.
Nominal Real Delay Percentage
5000 Circles 170.1 170.6 0.5 0.29%
15000 Circles 2855.5 2856.2 0.7 0.02%
30000 Circles 16802.5 16803.3 0.8 0.00%
60000 Circles 68969.1 68970.3 1.2 0.00%
Considering that after code ends, the command and AutoCAD need take the reasonable few CPU cycles to return and back to responsible, we can safely reach the conclusion that the Transaction approach does not have any delay at all.
Here is a graph to illustrate the nominal/real performance and the very reasonable tiny delay visually anyway.
As also can be noticed, the delays for all the four tests fall into a small range with all very tiny values, from half to 1.2 millisecond. The percentage delay becomes smaller if more entities are processed. In any case, the percentage always approaches to zero and the absolute value can be ignored.
Here is the chart to illustrate no delays of Transaction regardless of object count.
By the way, for readers’ reference, the above tests were performed in AutoCAD 2012 on Windows 7 with duo Intel CORE, exactly the same environment as we did to the ObjectId.Open/Close.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |