Author Topic: Relative speed of SelectionSets and Iterating a DB.  (Read 11679 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Relative speed of SelectionSets and Iterating a DB.
« on: March 15, 2008, 05:06:08 AM »
I may have learnt something today ... again :-).

I was perusing http://discussion.autodesk.com/thread.jspa?threadID=650451 and saw a recent discussion which provided VB code to collect all attributes from modelspace and write the values to a file.
The solution iterated the DB and tested each entity to see if it was a block, with attributes ; if so write the tag and value to a file.
[rinse and repeat]
From: caddie75
Date: Mar/15/08 - 06:42 (EST)
with [Attachment: Test_attReads.vb.txt]


I thought that Iterating the DB would be uber slow so I've put together a quick test to see how using a selection set compared.

I built a drawing which has 12103 entities mixed as simple ents, blocks without atts and attributed blocks.

this is the resulting output :

Command: Test_01
End eval...Process time: 0.34375 Seconds for 1980 records of 12103
Command: Test_02
End eval...Process time: 0.4375 Seconds for 1980 records of 12103

not much of a difference !

and the code :
note .. you may want to change the .txt file address or names.
The code could probable be optimised a little :-)

Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. using Autodesk.AutoCAD.ApplicationServices;
  8. using Autodesk.AutoCAD.DatabaseServices;
  9. using Autodesk.AutoCAD.EditorInput;
  10. using Autodesk.AutoCAD.Geometry;
  11. using Autodesk.AutoCAD.Runtime;
  12.  
  13. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  14. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  15. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  16. using AcEd = Autodesk.AutoCAD.EditorInput;
  17. using AcGe = Autodesk.AutoCAD.Geometry;
  18. using AcRx = Autodesk.AutoCAD.Runtime;
  19. //
  20. using AcUi = Autodesk.AutoCAD.Windows;
  21.  
  22.  
  23. namespace kdubTestingCommands
  24. {
  25.     public partial class TestCommands
  26.     {
  27.         //
  28.         // // CodeHimBelongaKwb ©  Mar 2008
  29.         //
  30.         [CommandMethod("Test_01")]
  31.         public void getBlocksTest()
  32.         {
  33.             DateTime TimeStart = DateTime.Now;
  34.             string FileNamePath = @"D:\EvalReport_01.txt";
  35.             Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  36.  
  37.             ObjectId[] selectedIDs = SelectBlockRefs03();
  38.             if (selectedIDs == null) return;
  39.  
  40.             StreamWriter LogFile_Obj = new StreamWriter(FileNamePath, true, System.Text.Encoding.ASCII);
  41.             LogFile_Obj.AutoFlush = true;
  42.             LogFile_Obj.WriteLine("Starting eval...");
  43.             int countAtts = 0;
  44.             Database db = AcDb.HostApplicationServices.WorkingDatabase;
  45.             AcDb.TransactionManager tm = AcadApp.DocumentManager.MdiActiveDocument.TransactionManager;
  46.  
  47.             using (Transaction tr = tm.StartTransaction())
  48.             {
  49.                 try
  50.                 {
  51.                     foreach (ObjectId entID in selectedIDs)
  52.                     {
  53.                         BlockReference blkRef = tr.GetObject(entID, OpenMode.ForRead, false)
  54.                             as BlockReference;
  55.                         foreach (ObjectId attId in blkRef.AttributeCollection)
  56.                         {
  57.                             AttributeReference attRef = tr.GetObject(attId, OpenMode.ForRead)
  58.                                 as AttributeReference;
  59.                             if (!(attRef == null))
  60.                             {
  61.                                 countAtts = countAtts + 1;
  62.                                 LogFile_Obj.WriteLine(countAtts.ToString() + '\t' +
  63.                                                  attRef.Tag + '\t' + attRef.TextString);
  64.                             }
  65.                         }
  66.                     }
  67.                     TimeSpan TimeDuration = (DateTime.Now - TimeStart);
  68.                     ed.WriteMessage("End eval...Process time: "
  69.                             + (TimeDuration.TotalSeconds + " Seconds for "
  70.                             + countAtts.ToString() + " records of "
  71.                             + db.ApproxNumObjects.ToString()));                    
  72.                     LogFile_Obj.WriteLine(("End eval...Process time: "
  73.                             + (TimeDuration.TotalSeconds + " Seconds.")));
  74.                 }
  75.                 catch
  76.                 {
  77.                     ed.WriteMessage("Ooops");
  78.                 }
  79.                 finally
  80.                 {
  81.                     LogFile_Obj.Close();
  82.                 }
  83.             }
  84.         }
  85.         //
  86.         // // CodeHimBelongaKwb ©  Mar 2008
  87.         //
  88.         static public ObjectId[] SelectBlockRefs03()
  89.         {
  90.             Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  91.             TypedValue[] tValues =
  92.                 { new TypedValue((int)DxfCode.Start, "INSERT"),
  93.                   new TypedValue((int)DxfCode.LayerName, "BLOCKS"),
  94.                   new TypedValue(410, "Model"),                  
  95.                   new TypedValue(66, 1) // hasAttributes ?
  96.                 };
  97.  
  98.             SelectionFilter sFilter = new SelectionFilter(tValues);
  99.  
  100.             PromptSelectionResult res = ed.SelectAll(sFilter);
  101.  
  102.             if (res.Status != PromptStatus.OK) return null;
  103.             return res.Value.GetObjectIds();
  104.         }
  105.  
  106.         //
  107.         // Translated from VB code AT http://discussion.autodesk.com/thread.jspa?threadID=650451
  108.         //
  109.         [CommandMethod("Test_02")]
  110.         public void Test_ReadWriteAttData()
  111.         {
  112.             DateTime TimeStart = DateTime.Now;
  113.             string FileNamePath = @"D:\EvalReport_02.txt";
  114.             Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  115.  
  116.             StreamWriter LogFile_Obj = new StreamWriter(FileNamePath, true, System.Text.Encoding.ASCII);
  117.             LogFile_Obj.AutoFlush = true;
  118.  
  119.             LogFile_Obj.WriteLine("Starting eval...");
  120.  
  121.             int countAtts = 0;
  122.  
  123.             Database db = AcDb.HostApplicationServices.WorkingDatabase;
  124.             AcDb.TransactionManager tm = AcadApp.DocumentManager.MdiActiveDocument.TransactionManager;
  125.  
  126.             using (Transaction tr = tm.StartTransaction())
  127.             {
  128.                 try
  129.                 {
  130.                     BlockTable table = tm.GetObject
  131.                           (db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
  132.                     BlockTableRecord modelSpace = tm.GetObject(table[BlockTableRecord.ModelSpace],
  133.                         OpenMode.ForWrite, false) as BlockTableRecord;
  134.  
  135.                     foreach (ObjectId objId in modelSpace)
  136.                     {
  137.                         Entity ent = tr.GetObject(objId, OpenMode.ForRead, false) as Entity;
  138.                         if (ent.GetType().FullName.Equals("Autodesk.AutoCAD.DatabaseServices.BlockReference"))
  139.                         {
  140.                             BlockReference blkRef = ent as BlockReference;
  141.                             if (blkRef.Layer == "BLOCKS")
  142.                             {
  143.                                 foreach (ObjectId attId in blkRef.AttributeCollection)
  144.                                 {
  145.                                     AttributeReference attRef = tr.GetObject(attId, OpenMode.ForRead)
  146.                                         as AttributeReference;
  147.                                     if (!(attRef == null))
  148.                                     {
  149.                                         countAtts = countAtts + 1;
  150.                                         LogFile_Obj.WriteLine(countAtts.ToString() + '\t' +
  151.                                                          attRef.Tag + '\t' + attRef.TextString);
  152.                                     }
  153.                                 }
  154.                             }
  155.                         }
  156.                     }
  157.                     TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
  158.                     ed.WriteMessage("End eval...Process time: "
  159.                             + (TimeDuration.TotalSeconds + " Seconds for "
  160.                             + countAtts.ToString() + " records of "
  161.                             + db.ApproxNumObjects.ToString()));
  162.                     LogFile_Obj.WriteLine(("End eval...Process time: "
  163.                             + (TimeDuration.TotalSeconds + " Seconds.")));
  164.                 }
  165.                 catch
  166.                 {
  167.                     ed.WriteMessage("Ooops");
  168.                 }
  169.                 finally
  170.                 {
  171.                     LogFile_Obj.Close();
  172.                 }
  173.             }
  174.         }
  175.     }
  176. }


edit:kdub code=csharp
« Last Edit: August 16, 2012, 10:18:05 PM by Kerry »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #1 on: March 15, 2008, 07:26:37 AM »
Code: [Select]
Command: Test_01
End eval...Process time: 0.1802592 Seconds for 923 records of 109993
Command: Test_02
End eval...Process time: 0.4306192 Seconds for 923 records of 109993

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #2 on: March 15, 2008, 07:51:11 AM »

Those relationships sound about right Daniel ..

The less blocks in the drawing the better the advantage of the SelectionSet methodology.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #3 on: March 15, 2008, 09:16:17 AM »

Those relationships sound about right Daniel ..

The less blocks in the drawing the better the advantage of the SelectionSet methodology.

I suspect that the selection set method will always be faster since it’s native code.

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #4 on: March 15, 2008, 04:20:14 PM »
Kerry,

For the benefit of the VB (cough) people who probably don't read C# code that well (if at all) ;), could you also state which test is which? ie. is Test_01 the selection set and Test_02 the database iteration or vice versa.

Also, I can't remember whether the filtered selectionset method will get a blockreference with attributes that is nested inside a blockreference that doesn't contain attributes, if you know what I mean.

Also (hate to repeat that word for another sentence), but the quickest way in my mind to accomplish the stated goal, would be to roll over the BlockTable (excluding layouts of course) and check the HasAttributeDefinitions property of each BlockTableRecord (BTR). If this is true, then use the GetBlockReferenceIds method to get the actual inserts and process from there...does that make sense?

I think you would find that this would out perform the selectionset approach...but I maybe wrong of course  :-)

Cheers,
Glenn.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #5 on: March 15, 2008, 09:33:36 PM »
Just so we can compare apples and other types of fruit,
native code will iterate though the DB using the same dwg at a smashing 0.030 seconds  :-o

Code: [Select]
static void GetAttributesBench_doit(void)
  {
    clock_t start, end;
    double diff;
    start = clock();
   
    Acad::ErrorStatus es;
    int counter = 0;

    wofstream out("D:\\EvalReport_03.txt");

    AcDbBlockTableRecord *pTableRecord;

    AcDbDatabase *pDatabase =
      acdbHostApplicationServices()->workingDatabase();

    AcDbBlockTablePointer
      pBlockTable(pDatabase,AcDb::kForRead);

    AcDbBlockTableIterator *pBlockTableIterator;
    pBlockTable->newIterator(pBlockTableIterator);

    for (pBlockTableIterator->start();
        !pBlockTableIterator->done();
        pBlockTableIterator->step())
    {
      es = pBlockTableIterator->getRecord(pTableRecord, AcDb::kForRead,Adesk::kFalse);
      if (es == Acad::eOk &&  pTableRecord->hasAttributeDefinitions() == Adesk::kTrue)
      {
        AcDbObjectIdArray blockReferenceIds;
        pTableRecord->getBlockReferenceIds(blockReferenceIds);

        for(int i = 0 ; i < blockReferenceIds.length() ; i++)
        {

          AcDbObjectPointer<AcDbBlockReference> pBlockReference
            (blockReferenceIds[i] , AcDb::kForRead,Adesk::kFalse);

          AcDbObjectIterator* pAttributeIterator;
          pAttributeIterator = pBlockReference->attributeIterator();

          for (pAttributeIterator->start();
              !pAttributeIterator->done();
               pAttributeIterator->step())
          {
            if ( wcscmp(pBlockReference->layer(), _T("1_8_TEXT")) == 0)
            {
              AcDbObjectPointer<AcDbAttribute> pAttribute
                (pAttributeIterator->objectId(),AcDb::kForRead,Adesk::kFalse);

              counter += 1;
              out << "\n" << counter << " " << pAttribute->tag() << " " << pAttribute->textString();
            }
          }
        }
        pTableRecord->close();
      }
    }
    delete pBlockTableIterator;
    out.close();
    end = clock();
    diff = ((double)(end - start)) / CLOCKS_PER_SEC;
    acutPrintf( _T("\n%2.3f seconds\n"), diff);
  }

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #6 on: March 16, 2008, 05:58:12 AM »
Dan, can you either post your dwg or try the same method in C# so we actually can compare :)

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #7 on: March 16, 2008, 06:27:07 AM »
this was the result of testing Kerrys code on the Same DWG
http://www.theswamp.org/index.php?topic=21930.msg264792#msg264792

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #8 on: March 16, 2008, 06:29:15 AM »
How about we make a test DWG to play with as this one is for a customer   :-D

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #9 on: March 16, 2008, 06:31:00 AM »
Out of curiosity, I ported this over to DRX, just to see how Bricscad would perform. I honestly thought AutoCAD would give this little clone a spanking, but to my amazement, the performance was identical at 0.030 seconds. Wow!

Code: [Select]
int doit()
{
  clock_t start, end;
  double diff;
  start = clock();
  int counter = 0;
  wofstream out("D:\\EvalReport_04.txt");

  OdApDocManager *pDocMan = odapDocManager();
  OdApDocument* pDoc = pDocMan->curDocument();
  OdDbDatabasePtr pDb = pDoc->database();
  OdDbObjectId blockTableId = pDb->getBlockTableId();
  OdDbBlockTablePtr pBlockTable = blockTableId.openObject(OdDb::kForRead);
  OdDbBlockTableIteratorPtr pBlockTableIterator = pBlockTable->newIterator();

  for (pBlockTableIterator->start();
      !pBlockTableIterator->done();
       pBlockTableIterator->step())
  {
    OdDbBlockTableRecordPtr pTableRecord = pBlockTableIterator->getRecord(OdDb::kForRead);
    if(pTableRecord->hasAttributeDefinitions() == true)
    {
      OdDbObjectIdArray blockReferenceIds;
      pTableRecord->getBlockReferenceIds(blockReferenceIds);

      for(int i = 0 ; i < blockReferenceIds.length() ; i++)
      {
        OdDbBlockReferencePtr pBlockReference = blockReferenceIds[i].openObject(OdDb::kForRead);
        OdDbObjectIteratorPtr pAttributeIterator = pBlockReference->attributeIterator();

        for (pAttributeIterator->start();
             !pAttributeIterator->done();
             pAttributeIterator->step())
        {
          if ( wcscmp(pBlockReference->layer(), _T("1_8_TEXT")) == 0)
          {
            OdDbAttributePtr pAttribute =
              pAttributeIterator->objectId().openObject(OdDb::kForRead);
            counter += 1;
            out << "\n" << counter << " " << pAttribute->tag() << " " << pAttribute->textString();
          }
        }
      }
    }
  }
  out.close();
  end = clock();
  diff = ((double)(end - start)) / CLOCKS_PER_SEC;
  sds_printf( _T("\n%2.3f seconds\n"), diff);
  return (RTNORM);
}



Sorry to hijack your thread Kerry

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #10 on: March 16, 2008, 07:12:00 AM »
this was the result of testing Kerrys code on the Same DWG
http://www.theswamp.org/index.php?topic=21930.msg264792#msg264792


That's not what I meant. Kerry's code uses the selset method and iterate modelspace methods to get the work done.
What I would like to see, is your last example in C++ (which did it the way I mentioned) ported to a C# equivalent and that tested against your dwg file.

I would do the code myself, but my wife is nagging at me to do the shopping, so I will be out for a bit. Also, it makes sense for you to test it on your dwg as you've been posting a few different time tests against the same sample set of data...if that makes sense.

I will have a ply when I return from the shopping throngs :)

Cheers,
Glenn.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #11 on: March 16, 2008, 08:56:15 AM »
<snip>

Sorry to hijack your thread Kerry


not a problem ...  just wish I could make the time to participate more.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #12 on: March 16, 2008, 08:59:50 AM »
Ah ok, yes much much faster at
End eval...Process time: 0.0701008 Seconds for 923 records of 109993

Good call Glenn  :kewl:

Code - C#: [Select]
  1.    [CommandMethod("Test_05")]
  2.     public void Test_ReadWriteAttData()
  3.     {
  4.       DateTime TimeStart = DateTime.Now;
  5.       string FileNamePath = @"D:\EvalReport_05.txt";
  6.       Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
  7.  
  8.       StreamWriter LogFile_Obj =
  9.         new StreamWriter(FileNamePath, true, System.Text.Encoding.ASCII);
  10.  
  11.       LogFile_Obj.AutoFlush = true;
  12.       LogFile_Obj.WriteLine("Starting eval...");
  13.  
  14.       int countAtts = 0;
  15.  
  16.       Database db = AcDb.HostApplicationServices.WorkingDatabase;
  17.  
  18.       AcDb.TransactionManager tm =
  19.         AcadApp.DocumentManager.MdiActiveDocument.TransactionManager;
  20.  
  21.       using (Transaction tr = tm.StartTransaction())
  22.       {
  23.         try
  24.         {
  25.           BlockTable blockTable = tr.GetObject
  26.             (db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
  27.  
  28.           foreach (ObjectId blockTableRecordId in blockTable)
  29.           {
  30.             BlockTableRecord blockTableRecord = tr.GetObject
  31.               (blockTableRecordId, OpenMode.ForRead, false) as BlockTableRecord;
  32.  
  33.             if (blockTableRecord.HasAttributeDefinitions == true)
  34.             {
  35.               ObjectIdCollection blockReferenceIds =
  36.                   blockTableRecord.GetBlockReferenceIds(false, false);
  37.  
  38.               foreach (ObjectId blockReferenceId in blockReferenceIds)
  39.               {
  40.                 BlockReference blockReference = tr.GetObject
  41.                   (blockReferenceId, OpenMode.ForRead, false) as BlockReference;
  42.  
  43.                 if (blockReference.Layer == "1_8_TEXT")
  44.                 {
  45.                   foreach (ObjectId attributeReferenceId in blockReference.AttributeCollection)
  46.                   {
  47.                     AttributeReference attributeReference = tr.GetObject
  48.                       (attributeReferenceId, OpenMode.ForRead) as AttributeReference;
  49.  
  50.                     countAtts = countAtts + 1;
  51.                     LogFile_Obj.WriteLine(countAtts.ToString() + '\t' +
  52.                           attributeReference.Tag + '\t' + attributeReference.TextString);
  53.                   }
  54.                 }
  55.               }
  56.             }
  57.           }
  58.           TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
  59.           ed.WriteMessage("End eval...Process time: "
  60.                   + (TimeDuration.TotalSeconds + " Seconds for "
  61.                   + countAtts.ToString() + " records of "
  62.                   + db.ApproxNumObjects.ToString()));
  63.           LogFile_Obj.WriteLine(("End eval...Process time: "
  64.                   + (TimeDuration.TotalSeconds + " Seconds.")));
  65.         }
  66.         catch(System.Exception ex)
  67.         {
  68.           ed.WriteMessage(ex.Message);
  69.           ed.WriteMessage(ex.StackTrace);
  70.         }
  71.         finally
  72.         {
  73.           LogFile_Obj.Close();
  74.         }
  75.       }
  76.     }
  77.  

edit:kdub code=csharp
« Last Edit: August 16, 2012, 10:20:20 PM by Kerry »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #13 on: March 16, 2008, 09:15:27 AM »

just a side issue.
the translation from the vb sample is not a pure translation ...I used a bit of artistic license :-)

It may be interesting to compile the VB code and test it too ... it will need a filter for layer added to be functionally comparative.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #14 on: March 16, 2008, 09:28:12 AM »
Ah ok, yes much much faster at
End eval...Process time: 0.0701008 Seconds for 923 records of 109993

Good call Glenn  :kewl:

Code: [Select]
   [CommandMethod("Test_05")]
    public void Test_ReadWriteAttData()
    {
      DateTime TimeStart = DateTime.Now;
      string FileNamePath = @"D:\EvalReport_05.txt";
      Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;

      StreamWriter LogFile_Obj =
        new StreamWriter(FileNamePath, true, System.Text.Encoding.ASCII);

      LogFile_Obj.AutoFlush = true;
      LogFile_Obj.WriteLine("Starting eval...");

      int countAtts = 0;

      Database db = AcDb.HostApplicationServices.WorkingDatabase;

      AcDb.TransactionManager tm =
        AcadApp.DocumentManager.MdiActiveDocument.TransactionManager;

      using (Transaction tr = tm.StartTransaction())
      {
        try
        {
          BlockTable blockTable = tr.GetObject
            (db.BlockTableId, OpenMode.ForRead, false) as BlockTable;

          foreach (ObjectId blockTableRecordId in blockTable)
          {
            BlockTableRecord blockTableRecord = tr.GetObject
              (blockTableRecordId, OpenMode.ForRead, false) as BlockTableRecord;

            if (blockTableRecord.HasAttributeDefinitions == true)
            {
              ObjectIdCollection blockReferenceIds =
                  blockTableRecord.GetBlockReferenceIds(false, false);

              foreach (ObjectId blockReferenceId in blockReferenceIds)
              {
                BlockReference blockReference = tr.GetObject
                  (blockReferenceId, OpenMode.ForRead, false) as BlockReference;

                if (blockReference.Layer == "1_8_TEXT")
                {
                  foreach (ObjectId attributeReferenceId in blockReference.AttributeCollection)
                  {
                    AttributeReference attributeReference = tr.GetObject
                      (attributeReferenceId, OpenMode.ForRead) as AttributeReference;

                    countAtts = countAtts + 1;
                    LogFile_Obj.WriteLine(countAtts.ToString() + '\t' +
                          attributeReference.Tag + '\t' + attributeReference.TextString);
                  }
                }
              }
            }
          }
          TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
          ed.WriteMessage("End eval...Process time: "
                  + (TimeDuration.TotalSeconds + " Seconds for "
                  + countAtts.ToString() + " records of "
                  + db.ApproxNumObjects.ToString()));
          LogFile_Obj.WriteLine(("End eval...Process time: "
                  + (TimeDuration.TotalSeconds + " Seconds.")));
        }
        catch(System.Exception ex)
        {
          ed.WriteMessage(ex.Message);
          ed.WriteMessage(ex.StackTrace);
        }
        finally
        {
          LogFile_Obj.Close();
        }
      }
    }


Dan,

Here is my take on it for the sake of completeness. If you can, can you run against your dataset and post the results. I haven't tested this at all btw.
Gimme another half hour or so and I might have another way that will beat even that C# one you posted recently.

Code - C#: [Select]
  1. [CommandMethod("Test_03")]
  2. public static void test03Command()
  3. {        
  4.         Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.         Database db = doc.Database;
  6.         Editor ed = doc.Editor;
  7.  
  8.         DateTime TimeStart = DateTime.Now;
  9.  
  10.     string outputFileName = @"C:\Temp\EvalReport_03.txt";
  11.  
  12.     int attributeCount = 0;
  13.  
  14.         Transaction tr = null;
  15.         StreamWriter logFileWriter = null;
  16.  
  17.         try
  18.         {
  19.                 logFileWriter = new StreamWriter(outputFileName, true, System.Text.Encoding.ASCII);
  20.                 logFileWriter.AutoFlush = true;
  21.                 logFileWriter.WriteLine("Starting eval...");
  22.  
  23.                 tr = db.TransactionManager.StartTransaction();
  24.  
  25.                 BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) as BlockTable;
  26.                 if (bt == null)
  27.                 {
  28.                         ed.WriteMessage("{0}Catastrophic error: Failed to open the BlockTable!", Environment.NewLine);
  29.                         return;
  30.                 }
  31.  
  32.                 // roll over the block table
  33.                 foreach (ObjectId btrId in bt)
  34.                 {
  35.                         BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead, false) as BlockTableRecord;
  36.                         if (btr == null)
  37.                         {
  38.                                 ed.WriteMessage("{0}Serious error: Failed to open a BlockTableRecord! Continuing...", Environment.NewLine);
  39.                                 continue;
  40.                         }
  41.  
  42.                         if (!btr.HasAttributeDefinitions)
  43.                                 continue;
  44.  
  45.                         ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(false, false);
  46.                         if (blkRefIds == null || blkRefIds.Count == 0)
  47.                                 continue;
  48.  
  49.                         foreach (ObjectId blkRefId in blkRefIds)
  50.                         {
  51.                                 BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
  52.                                 if (blkRef == null)
  53.                                 {
  54.                                         ed.WriteMessage("{0}Serious error: Failed to open a BlockReference! Continuing...", Environment.NewLine);
  55.                                         continue;
  56.                                 }
  57.  
  58.                                 if (blkRef.Layer != "BLOCKS")
  59.                                         continue;
  60.  
  61.                                 AttributeCollection attRefIds = blkRef.AttributeCollection;
  62.                                 if (attRefIds == null || attRefIds.Count == 0)
  63.                                         continue;
  64.  
  65.                                 foreach (ObjectId attRefId in attRefIds)
  66.                                 {
  67.                                         AttributeReference attRef = tr.GetObject(attRefId, OpenMode.ForRead, false) as AttributeReference;
  68.                                         if (attRef == null)
  69.                                         {
  70.                                                 ed.WriteMessage("{0}Serious error: Failed to open an AttributeReference! Continuing...", Environment.NewLine);
  71.                                                 continue;
  72.                                         }
  73.  
  74.                                         attributeCount++;
  75.  
  76.                                         logFileWriter.WriteLine(attributeCount.ToString() + '\t' + attRef.Tag + '\t' + attRef.TextString);
  77.                                 }
  78.                         }
  79.                 }
  80.  
  81.                 tr.Commit();
  82.  
  83.                 TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
  84.  
  85.                 ed.WriteMessage("End eval...Process time: "
  86.                                 + (TimeDuration.TotalSeconds + " Seconds for "
  87.                                 + attributeCount.ToString() + " records of "
  88.                                 + db.ApproxNumObjects.ToString()));
  89.  
  90.                 logFileWriter.WriteLine(("End eval...Process time: " + (TimeDuration.TotalSeconds + " Seconds.")));
  91.         }
  92.         catch (Autodesk.AutoCAD.Runtime.Exception arex)
  93.         {
  94.                 ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, arex.Message);
  95.                 return;
  96.         }
  97.         catch (System.Exception ex)
  98.         {
  99.                 ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.Message);
  100.                 return;
  101.         }
  102.         finally
  103.         {
  104.                 if (tr != null)
  105.                         tr.Dispose();
  106.  
  107.                 if (logFileWriter != null)
  108.                         logFileWriter.Close();
  109.         }
  110.  
  111. }
  112.  

Cheers,
Glenn.

edit:kdub code=csharp
« Last Edit: August 16, 2012, 10:25:49 PM by Kerry »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #15 on: March 16, 2008, 09:38:12 AM »
nice coding  8-)

End eval...Process time: 0.0801152 Seconds for 923 records of 109993

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #16 on: March 16, 2008, 10:10:27 AM »
Dan,

I can't get the below to work on my machine, so can you give it a try...I think you see where I'm headed with it :)

Code - C#: [Select]
  1. [CommandMethod("Test_04")]
  2. public static void test04Command()
  3. {
  4.         Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.         Database db = doc.Database;
  6.         Editor ed = doc.Editor;
  7.  
  8.         DateTime TimeStart = DateTime.Now;
  9.  
  10.         string outputFileName = @"C:\Temp\EvalReport_04.txt";
  11.  
  12.         int attributeCount = 0;
  13.  
  14.         StreamWriter logFileWriter = null;
  15.  
  16.         try
  17.         {
  18.                 logFileWriter = new StreamWriter(outputFileName, true, System.Text.Encoding.ASCII);
  19.                 logFileWriter.AutoFlush = true;
  20.                 logFileWriter.WriteLine("Starting eval...");
  21.  
  22.                 ObjectId btId = db.BlockTableId;
  23.                 if (btId.IsNull || !btId.IsValid)
  24.                 {
  25.                         ed.WriteMessage("{0}Serious error: Failed to get BlockTable ObjectId!.", Environment.NewLine);
  26.                         return;
  27.                 }
  28.  
  29.                 BlockTable bt = btId.Open(OpenMode.ForRead, false) as BlockTable;
  30.                 if (bt == null)
  31.                 {
  32.                         ed.WriteMessage("{0}Catastrophic error: Failed to open the BlockTable!", Environment.NewLine);
  33.                         return;
  34.                 }
  35.  
  36.                 // roll over the block table
  37.                 foreach (ObjectId btrId in bt)
  38.                 {
  39.                         //BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead, false) as BlockTableRecord;
  40.                         BlockTableRecord btr = btrId.Open(OpenMode.ForRead, false) as BlockTableRecord;
  41.                         if (btr == null)
  42.                         {
  43.                                 ed.WriteMessage("{0}Serious error: Failed to open a BlockTableRecord! Continuing...", Environment.NewLine);
  44.                                 continue;
  45.                         }
  46.  
  47.                         if (!btr.HasAttributeDefinitions)
  48.                         {
  49.                                 btr.Close();
  50.                                 continue;
  51.                         }
  52.  
  53.                         ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(false, false);
  54.                         if (blkRefIds == null || blkRefIds.Count == 0)
  55.                                 continue;
  56.  
  57.                         foreach (ObjectId blkRefId in blkRefIds)
  58.                         {
  59.                                 //BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
  60.                                 BlockReference blkRef = blkRefId.Open(OpenMode.ForRead, false) as BlockReference;
  61.                                 if (blkRef == null)
  62.                                 {
  63.                                         ed.WriteMessage("{0}Serious error: Failed to open a BlockReference! Continuing...", Environment.NewLine);
  64.                                         continue;
  65.                                 }
  66.  
  67.                                 if (blkRef.Layer != "BLOCKS")
  68.                                 {
  69.                                         blkRef.Close();
  70.                                         continue;
  71.                                 }
  72.  
  73.                                 AttributeCollection attRefIds = blkRef.AttributeCollection;
  74.                                 if (attRefIds == null || attRefIds.Count == 0)
  75.                                 {
  76.                                         blkRef.Close();
  77.                                         continue;
  78.                                 }
  79.  
  80.                                 foreach (ObjectId attRefId in attRefIds)
  81.                                 {
  82.                                         //AttributeReference attRef = tr.GetObject(attRefId, OpenMode.ForRead, false) as AttributeReference;
  83.                                         AttributeReference attRef = attRefId.Open(OpenMode.ForRead, false) as AttributeReference;
  84.                                         if (attRef == null)
  85.                                         {
  86.                                                 ed.WriteMessage("{0}Serious error: Failed to open an AttributeReference! Continuing...", Environment.NewLine);
  87.                                                 continue;
  88.                                         }
  89.  
  90.                                         attributeCount++;
  91.  
  92.                                         logFileWriter.WriteLine(attributeCount.ToString() + '\t' + attRef.Tag + '\t' + attRef.TextString);
  93.  
  94.                                         attRef.Close();
  95.                                 }
  96.  
  97.                                 blkRef.Close();
  98.                         }
  99.                 }
  100.  
  101.                 //tr.Commit();
  102.                 bt.Close();
  103.  
  104.                 TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
  105.  
  106.                 ed.WriteMessage("End eval...Process time: "
  107.                                 + (TimeDuration.TotalSeconds + " Seconds for "
  108.                                 + attributeCount.ToString() + " records of "
  109.                                 + db.ApproxNumObjects.ToString()));
  110.  
  111.                 logFileWriter.WriteLine(("End eval...Process time: " + (TimeDuration.TotalSeconds + " Seconds.")));
  112.         }
  113.         catch (Autodesk.AutoCAD.Runtime.Exception arex)
  114.         {
  115.                 ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, arex.Message);
  116.                 return;
  117.         }
  118.         catch (System.Exception ex)
  119.         {
  120.                 ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
  121.                 return;
  122.         }
  123.         finally
  124.         {
  125.                 if (logFileWriter != null)
  126.                         logFileWriter.Close();
  127.         }
  128.  
  129. }
  130.  

Cheers,
Glenn.


edit:kdub code=csharp
« Last Edit: August 16, 2012, 10:21:00 PM by Kerry »

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #17 on: March 16, 2008, 10:11:25 AM »
It's probably something simple that I'm overlooking...

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #18 on: March 16, 2008, 10:26:46 AM »
Interesting. I got it to work in AutoCAD 2006 and 2007 by SPECIFICALLY linking against those particular managed dll's for each product.

It is a bit faster, even more so when it's been jitted...I think you might find it get's down close to the ARX solution...which is how I would have done it btw.

Cheers,
Glenn.

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #19 on: March 16, 2008, 10:43:45 AM »
OK, I got it to work in 2008 as well, linking against the managed 2008 libraries.

The error being thrown was a null reference exception from ObjectId.GetObject() even though I wasn't using that. It appears that Object.Open in 2008 forwards a call to ObjectId.GetObject() which requires a top level transaction.

So, I added a transacton in, but still using ObjectId.Open() and voila.

Updated code for those masochists amongst us:

Code - C#: [Select]
  1. [CommandMethod("Test_04")]
  2. public static void test04Command()
  3. {
  4.         Document doc = acadApp.DocumentManager.MdiActiveDocument;
  5.         Database db = doc.Database;
  6.         Editor ed = doc.Editor;
  7.  
  8.         DateTime TimeStart = DateTime.Now;
  9.  
  10.         string outputFileName = @"C:\Temp\EvalReport_04.txt";
  11.  
  12.         int attributeCount = 0;
  13.  
  14.         Transaction tr = null;
  15.         StreamWriter logFileWriter = null;
  16.  
  17.         try
  18.         {
  19.                 logFileWriter = new StreamWriter(outputFileName, true, System.Text.Encoding.ASCII);
  20.                 logFileWriter.AutoFlush = true;
  21.                 logFileWriter.WriteLine("Starting eval...");
  22.  
  23.                 tr = db.TransactionManager.StartTransaction();
  24.  
  25.                 ObjectId btId = db.BlockTableId;
  26.                 if (btId.IsNull || !btId.IsValid)
  27.                 {
  28.                         ed.WriteMessage("{0}Serious error: Failed to get BlockTable ObjectId!.", Environment.NewLine);
  29.                         return;
  30.                 }
  31.  
  32.                 BlockTable bt = btId.Open(OpenMode.ForRead, false) as BlockTable;
  33.                 if (bt == null)
  34.                 {
  35.                         ed.WriteMessage("{0}Catastrophic error: Failed to open the BlockTable!", Environment.NewLine);
  36.                         return;
  37.                 }
  38.  
  39.                 // roll over the block table
  40.                 foreach (ObjectId btrId in bt)
  41.                 {
  42.                         //BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead, false) as BlockTableRecord;
  43.                         BlockTableRecord btr = btrId.Open(OpenMode.ForRead, false) as BlockTableRecord;
  44.                         if (btr == null)
  45.                         {
  46.                                 ed.WriteMessage("{0}Serious error: Failed to open a BlockTableRecord! Continuing...", Environment.NewLine);
  47.                                 continue;
  48.                         }
  49.  
  50.                         if (!btr.HasAttributeDefinitions)
  51.                         {
  52.                                 btr.Close();
  53.                                 continue;
  54.                         }
  55.  
  56.                         ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(false, false);
  57.                         if (blkRefIds == null || blkRefIds.Count == 0)
  58.                                 continue;
  59.  
  60.                         foreach (ObjectId blkRefId in blkRefIds)
  61.                         {
  62.                                 //BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
  63.                                 BlockReference blkRef = blkRefId.Open(OpenMode.ForRead, false) as BlockReference;
  64.                                 if (blkRef == null)
  65.                                 {
  66.                                         ed.WriteMessage("{0}Serious error: Failed to open a BlockReference! Continuing...", Environment.NewLine);
  67.                                         continue;
  68.                                 }
  69.  
  70.                                 if (blkRef.Layer != "BLOCKS")
  71.                                 {
  72.                                         blkRef.Close();
  73.                                         continue;
  74.                                 }
  75.  
  76.                                 AttributeCollection attRefIds = blkRef.AttributeCollection;
  77.                                 if (attRefIds == null || attRefIds.Count == 0)
  78.                                 {
  79.                                         blkRef.Close();
  80.                                         continue;
  81.                                 }
  82.  
  83.                                 foreach (ObjectId attRefId in attRefIds)
  84.                                 {
  85.                                         //AttributeReference attRef = tr.GetObject(attRefId, OpenMode.ForRead, false) as AttributeReference;
  86.                                         AttributeReference attRef = attRefId.Open(OpenMode.ForRead, false) as AttributeReference;
  87.                                         if (attRef == null)
  88.                                         {
  89.                                                 ed.WriteMessage("{0}Serious error: Failed to open an AttributeReference! Continuing...", Environment.NewLine);
  90.                                                 continue;
  91.                                         }
  92.  
  93.                                         attributeCount++;
  94.  
  95.                                         logFileWriter.WriteLine(attributeCount.ToString() + '\t' + attRef.Tag + '\t' + attRef.TextString);
  96.  
  97.                                         attRef.Close();
  98.                                 }
  99.  
  100.                                 blkRef.Close();
  101.                         }
  102.                 }
  103.  
  104.                 bt.Close();
  105.  
  106.                 tr.Commit();
  107.  
  108.                 TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;
  109.  
  110.                 ed.WriteMessage("End eval...Process time: "
  111.                                 + (TimeDuration.TotalSeconds + " Seconds for "
  112.                                 + attributeCount.ToString() + " records of "
  113.                                 + db.ApproxNumObjects.ToString()));
  114.  
  115.                 logFileWriter.WriteLine(("End eval...Process time: " + (TimeDuration.TotalSeconds + " Seconds.")));
  116.         }
  117.         catch (Autodesk.AutoCAD.Runtime.Exception arex)
  118.         {
  119.                 ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, arex.Message);
  120.                 return;
  121.         }
  122.         catch (System.Exception ex)
  123.         {
  124.                 ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
  125.                 return;
  126.         }
  127.         finally
  128.         {
  129.                 if (tr != null)
  130.                         tr.Dispose();
  131.                 if (logFileWriter != null)
  132.                         logFileWriter.Close();
  133.         }
  134.  
  135. }
  136.  

If you want to see the error I mentioned, just comment out all the transaction lines.

Cheers,
Glenn.


edit:kdub code=csharp
« Last Edit: August 16, 2012, 10:21:39 PM by Kerry »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #20 on: March 16, 2008, 11:51:41 AM »
I guess they really want you to use the transaction manager :) This one ran a little slower
… End eval...Process time: 0.1301872 Seconds for 923 records of 109993 very strange.
It would be interesting to put these under a profiler to see where the actual bottleneck is.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #21 on: March 17, 2008, 11:23:31 AM »
I posted this once before,  but removed it after I noticed I screwed up.
I wonder if someone with a dual/quad core processor or multi-processor machine ,
.NET 3.5 and VS 2008(express is ok), that’s feeling brave might want to test this for me.  :wink:

You will need to install this
http://www.microsoft.com/downloads/details.aspx?FamilyID=e848dc1d-5be3-4941-8705-024bc7f180ba&displaylang=en

In theory, this code should run approximately the same speed on single cores and faster on multi cores. The commands are test1 and test2 that make files c:\EvalReport_01.txt and c:\EvalReport_02.txt,

I have attached the solution and dlls


Edit: Ps test it on a COPY of a BIG drawing with lots of blocks and attributes and stuff
« Last Edit: March 18, 2008, 02:49:51 AM by Daniel »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #22 on: March 18, 2008, 05:08:01 AM »
Command: Test2
Process time: 0.03125 Seconds for 12103 Objects

except It doesn't add data to the file :-)

Test1
Command: Test1

 Thread ID15
Process time: 0.0625 Seconds for 12103 Objects

ditto .. no data in file   :|

but it is fast !   :-P

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #23 on: March 18, 2008, 05:20:28 AM »
Kerry ,

Thanks very much for trying this  8-)

Test1 should have been faster than Test2, but it’s good news that test1 did not throw an exception in reading the database from multiple threads

Maybe it didn’t write the file because I have changed the path to C:\ .. or because I changed the layer? It would be interesting to see test1's output to see how many thread were spawned. Anyway I really need to get myself a new computer  :lol:

Thanks again Kerry

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #24 on: March 18, 2008, 06:42:27 AM »
I'm an idgit !!

the word layer nudged me ..

Command: _laycur

Select objects to be changed to the current layer: Specify opposite corner:
6930 found

Select objects to be changed to the current layer:

6930 objects changed to layer "1_8_TEXT" (the current layer).
Command: netload

Command: test1

 Thread ID14
Process time: 0.484375 Seconds for 12107 Objects
Command: Test1
 Thread ID18
Process time: 0.203125 Seconds for 12107 Objects

Command: test2
Process time: 0.3125 Seconds for 12107 Objects
Command: Test2
Process time: 0.359375 Seconds for 12107 Objects
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #25 on: March 18, 2008, 06:58:43 AM »
Outstanding!! Thank you. It seems there is a little JIT time on the first run, which is OK. It wasn’t a doubling of speed, but I would say this is a pretty big increase
Did it generate an output file?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #26 on: March 18, 2008, 08:32:11 AM »

Yes, generated one thread only.
both runs used #16.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8691
  • AKA Daniel
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #27 on: March 18, 2008, 09:34:39 AM »
Hmm, Thanks,
I guess I need to study this more, What’s interesting is that the thread ID on your command line jumped from 14 to 18 where mine jumps by one thread at a time.
I wonder if the text writer spawned its own thread…

Now I have an excuse to go and purchase a new computer.  ;-)

Thanks again for your help

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #28 on: March 19, 2008, 05:09:35 AM »
<   >
So, I added a transacton in, but still using ObjectId.Open() and voila.

Updated code for those masochists amongst us:

Code: [Select]
[CommandMethod("Test_04")]
public static void test04Command()
{
//<>
}

If you want to see the error I mentioned, just comment out all the transaction lines.

Cheers,
Glenn.

nice looking code Glenn .. I'll have a better look over the weekend ; after I've finished the chocolate egg hunt  ;-)


btw:
chasing the last 1/10 of a second falls second to having maintainable and safe code ... but I think we've discussed this previously ...

« Last Edit: March 19, 2008, 05:12:55 AM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Relative speed of SelectionSets and Iterating a DB.
« Reply #29 on: March 19, 2008, 05:15:32 AM »
Thanks Kerry.

Yes we have discussed the speeeeed vs. purdiness issues before and I agree with you.

Cheers,
Glenn.