Transaction与OpenCloseTransaction效率分析
前些天在群里讨论到Transaction读写实体的效率问题,今天就做了一段代码说明一下Transaction的效.Transaction是什么东西这里就不做讨论了,有兴趣的朋友可以在论坛里面搜索以前的帖子. Transaction有一个子类,叫做OpenCloseTransation,在文档中这样描述它
This class may be used instead of the transaction class in certain scenarios..It wraps the ObjectId.Open/Close functions, but makes it easier to correctly pair these functions by storing references to every object opened and automatically closing them.
也就是说在对实体进行打开关闭操作的时候,它可以替代Transaction类. 我们通过下面代码来测试OpenCloseTransation和Transaction的效率上的区别.
[CommandMethod("GetTransTime")]
public void GetTransTime() {
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Stopwatch watch = new Stopwatch();
PromptSelectionResult res = ed.SelectAll();
if (res.Status != PromptStatus.OK) {
return;
}
ed.WriteMessage("\nCount of entities : {0}", res.Value.Count.ToString());
watch.Start();
using (Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()) {
foreach (ObjectId id in res.Value.GetObjectIds()) {
Entity ent = trans.GetObject(id, OpenMode.ForWrite) as Entity;
ent.ColorIndex = 1;
}
trans.Commit();
}
watch.Stop();
ed.WriteMessage("\nOne Transaction write cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
using (Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()) {
foreach (ObjectId id in res.Value.GetObjectIds()) {
Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
int nColor = ent.ColorIndex;
}
}
watch.Stop();
ed.WriteMessage("\nOne Transaction read cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
using (OpenCloseTransaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartOpenCloseTransaction()) {
foreach (ObjectId id in res.Value.GetObjectIds()) {
Entity ent = trans.GetObject(id, OpenMode.ForWrite) as Entity;
ent.ColorIndex = 2;
}
trans.Commit();
}
watch.Stop();
ed.WriteMessage("\nOne OpenCloseTransaction write cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
using (OpenCloseTransaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartOpenCloseTransaction()) {
foreach (ObjectId id in res.Value.GetObjectIds()) {
Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
int nColor = ent.ColorIndex;
}
}
watch.Stop();
ed.WriteMessage("\nOne OpenCloseTransaction read cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
foreach (ObjectId id in res.Value.GetObjectIds()) {
using (OpenCloseTransaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartOpenCloseTransaction()) {
Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
int nColor = ent.ColorIndex;
}
}
watch.Stop();
ed.WriteMessage("\nMulty OpenCloseTransaction read cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
foreach (ObjectId id in res.Value.GetObjectIds()) {
using (Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction()) {
Entity ent = trans.GetObject(id, OpenMode.ForRead) as Entity;
int nColor = ent.ColorIndex;
}
}
watch.Stop();
ed.WriteMessage("\nMulty Transaction read cost: {0}(ms)", watch.ElapsedMilliseconds.ToString());
}
上述代码在VS 2017 + Civil3d 2016中对于一张现有图形的运行结果如下
命令: GETTRANSTIME
Count of entities : 4124
One Transaction write cost: 782(ms)
One Transaction read cost: 60(ms)
One OpenCloseTransaction write cost: 241(ms)
One OpenCloseTransaction read cost: 5(ms)
Multy OpenCloseTransaction read cost: 36(ms)
Multy Transaction read cost: 51201(ms)
我们由此可以得到一个结论,OpenCloseTransation对于处理实体的读操作,效率比Transaction要高很多, 特别是需要处理多个事务时,效率提升更加明显.并且,一次一个Transaction处理多个实体,比每个实体新建一个Transaction效率要高的多.