河伯 发表于 2010-12-12 06:39:30

另外Id.GetObject的耗时远远大于tr.GetObject的

还有这事?真没测试过。

chpmould 发表于 2010-12-12 08:24:12

谢谢老师的指导...

雪山飞狐_lzh 发表于 2010-12-12 13:06:43

测试代码      
      public static void test21()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            Random rand = new Random();
            int num = ed.GetInteger("\n输入点数:").Value;

            using (var tr = db.TransactionManager.StartTransaction())
            {

                db.Pdmode = 35;
                db.Pdsize = -2;

                var pnts =
                  Enumerable
                  .Range(0, num)
                  .Select(i => new DBPoint(new Point3d(rand.NextDouble() * 100, rand.NextDouble() * 100, 0)));

                var btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                foreach (var pnt in pnts)
                {
                  btr.AppendEntity(pnt);
                  tr.AddNewlyCreatedDBObject(pnt, true);
                }
                tr.Commit();
            }

      }      
      public static void TransTest()
      {

            var db = HostApplicationServices.WorkingDatabase;
            var doc = Application.DocumentManager.GetDocument(db);
            var ed = doc.Editor;

            var resSel = ed.SelectAll();
            if (resSel.Status != PromptStatus.OK) return;

            var ss = resSel.Value.GetObjectIds();
            ed.WriteMessage("\n总共{0}个实体", ss.Length);

            Stopwatch watch = new Stopwatch();

            watch.Start();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (var id in ss)
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                  int color = ent.ColorIndex;
                  ent.ColorIndex = 1;
                }
                tr.Commit();
            }
            watch.Stop();
            ed.WriteMessage("\n单事务使用tr.GetObject(StartTransaction)耗时:{0}毫秒", watch.ElapsedMilliseconds);

            //watch.Reset();
            //watch.Start();
            //using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
            //{
            //    foreach (var id in ss)
            //    {
            //      Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
            //      int color = ent.ColorIndex;
            //      ent.ColorIndex = 2;
            //    }
            //    tr.Commit();
            //}
            //watch.Stop();
            //ed.WriteMessage("\n单事务使用tr.GetObject(StartOpenCloseTransaction)耗时:{0}毫秒", watch.ElapsedMilliseconds);

            watch.Reset();
            watch.Start();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (var id in ss)
                {
                  Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
                  int color = ent.ColorIndex;
                  ent.ColorIndex = 3;
                }
                tr.Commit();
            }
            watch.Stop();
            ed.WriteMessage("\n单事务使用id.GetObject耗时:{0}毫秒", watch.ElapsedMilliseconds);

            watch.Reset();
            watch.Start();
            foreach (var id in ss)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                  int color = ent.ColorIndex;
                  ent.ColorIndex = 4;
                  tr.Commit();
                }
            }
            watch.Stop();
            ed.WriteMessage("\n多事务使用tr.GetObject(StartTransaction)耗时:{0}毫秒", watch.ElapsedMilliseconds);

            //watch.Reset();
            //watch.Start();
            //foreach (var id in ss)
            //{
            //    using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
            //    {
            //      Entity ent = tr.GetObject(id, OpenMode.ForWrite) as Entity;
            //      int color = ent.ColorIndex;
            //      ent.ColorIndex = 5;
            //      tr.Commit();
            //    }
            //}
            //watch.Stop();
            //ed.WriteMessage("\n多事务使用tr.GetObject(StartOpenCloseTransaction)耗时:{0}毫秒", watch.ElapsedMilliseconds);

            watch.Reset();
            watch.Start();
            foreach (var id in ss)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                  Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
                  int color = ent.ColorIndex;
                  ent.ColorIndex = 6;
                  tr.Commit();
                }
            }
            watch.Stop();
            ed.WriteMessage("\n多事务使用id.GetObject耗时:{0}毫秒", watch.ElapsedMilliseconds);


      }结果:命令: transtest
总共10000个实体
单事务使用tr.GetObject(StartTransaction)耗时:394毫秒
单事务使用id.GetObject耗时:322毫秒
多事务使用tr.GetObject(StartTransaction)耗时:642毫秒
多事务使用id.GetObject耗时:676毫秒
命令:TRANSTEST
总共10000个实体
单事务使用tr.GetObject(StartTransaction)耗时:329毫秒
单事务使用id.GetObject耗时:318毫秒
多事务使用tr.GetObject(StartTransaction)耗时:631毫秒
多事务使用id.GetObject耗时:667毫秒
命令: tt1
input number of points: 50000
命令: transtest
总共60000个实体
单事务使用tr.GetObject(StartTransaction)耗时:1773毫秒
单事务使用id.GetObject耗时:1963毫秒
多事务使用tr.GetObject(StartTransaction)耗时:3899毫秒
多事务使用id.GetObject耗时:4155毫秒
命令: tt1
input number of points: 40000
命令: transtest
总共100000个实体
单事务使用tr.GetObject(StartTransaction)耗时:3011毫秒
单事务使用id.GetObject耗时:3426毫秒
多事务使用tr.GetObject(StartTransaction)耗时:6832毫秒
多事务使用id.GetObject耗时:7142毫秒

雪山飞狐_lzh 发表于 2010-12-12 13:10:05

在单事务中两者相差并不大,甚至实体较少时id.GetObject还快些
多事务id.GetObject就很慢了
另外高版本使用StartOpenCloseTransaction效率更好
这个可以看看忽悠悠的测试
http://www.objectarx.net/forum.php?mod=viewthread&tid=4797&extra=page%3D1

hmxmylove 发表于 2010-12-12 14:55:28

ID.getobject在没有事务打开的时候就会出错。

河伯 发表于 2010-12-12 16:38:06

01.命令: transtest
02.总共10000个实体
03.单事务使用tr.GetObject(StartTransaction)耗时:394毫秒

这些测试很有意义,效果很明显,看来处理多个对象时应该用tr.Getobject,反正也不增加代码量。
估计,Transaction与OpenCloseTransaction应该各有其适用性,只是目前文档匮乏,找不到更多依据。
页: 1 [2]
查看完整版本: 集合对象转换为Entity对象