Author Topic: Selection Filter vs. Btr Iterating  (Read 3327 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Selection Filter vs. Btr Iterating
« on: January 29, 2011, 09:59:18 PM »
Well I guess they both iterate so title is not correct.

I used drawing random points.dwg from this Post


Testing to fill a Point3dCollection

Maybe not a good test(Sure someone will reply if not), but using a SelectionFilter at least took 2 as long sometimes more.

Code: [Select]
[CommandMethod("TimeTest")]
 public void TimeTest()
 {
     Point3dCollection pntsSS = new Point3dCollection();
     Point3dCollection pntsIter = new Point3dCollection();
         
     Document doc = Application.DocumentManager.MdiActiveDocument;
     Database db = doc.Database;
     Editor ed = doc.Editor;
     
     using (Transaction trx = db.TransactionManager.StartTransaction())
     {
         Stopwatch sw = Stopwatch.StartNew();
         BlockTableRecord btr = trx.GetObject(db.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord;
         
         foreach (ObjectId id in btr)
         {
             DBPoint dbPnt = trx.GetObject(id, OpenMode.ForRead) as DBPoint;
             if (dbPnt != null)
                 pntsIter.Add(dbPnt.Position);
         }
         
         sw.Stop();
         ed.WriteMessage("\nItterating " + sw.ElapsedMilliseconds.ToString());
         sw.Reset();
               
         sw.Start();

         SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue((int)DxfCode.Start, "POINT") });
         PromptSelectionResult psr = ed.SelectAll(sf);

         foreach (SelectedObject so in psr.Value)
         {
             DBPoint dbPnt = trx.GetObject(so.ObjectId, OpenMode.ForRead) as DBPoint;
             pntsSS.Add(dbPnt.Position);
         }

         sw.Stop();
         ed.WriteMessage("\nSelection Filter " + sw.ElapsedMilliseconds.ToString());

         trx.Commit();
   
     }
 }

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8743
  • AKA Daniel
Re: Selection Filter vs. Btr Iterating
« Reply #1 on: January 30, 2011, 06:19:51 AM »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Selection Filter vs. Btr Iterating
« Reply #2 on: January 30, 2011, 06:41:59 AM »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Selection Filter vs. Btr Iterating
« Reply #3 on: January 30, 2011, 06:50:14 AM »
see this thread http://www.theswamp.org/index.php?topic=21930.0

jeeze time flies !!

 ... I think I need to take up full time coding again.

Use it or lose it, heh ?
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.

kaefer

  • Guest
Re: Selection Filter vs. Btr Iterating
« Reply #4 on: January 30, 2011, 07:08:37 AM »
see this thread http://www.theswamp.org/index.php?topic=21930.0

I guess this is the executive summary of that thread:

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

Replacing blocks with Objects We're Interested In: As the quotient of OWII/Total number of objects in BTR approaches zero, iterating takes ever more time relative to a SelectionSet.

Regards

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8743
  • AKA Daniel
Re: Selection Filter vs. Btr Iterating
« Reply #5 on: January 30, 2011, 07:21:48 AM »
As the quotient of OWII/Total number of objects in BTR approaches zero, iterating takes ever more time relative to a SelectionSet.

why?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8743
  • AKA Daniel
Re: Selection Filter vs. Btr Iterating
« Reply #6 on: January 30, 2011, 07:51:02 AM »
Actually, my guess is that Editor.SelectAll with a filter, iterates the database and uses AcRxObject::IsA()  to filter the set.  Selection sets should always be slightly slower than explicitly iterating, as there's a whole host of other things that happen in this process, I.e. firing off selection events, persisting the state of the set, in case a select previous needed, etc.  Plus the filter needs to be parsed through some sort of regex function.

In the case with .NET, using the 'as' keyword and a test for null is pretty efficient as its using the framework's type testing, so the object  does not need to call the underlying AcRxObject::IsA()  method.

Cheers  :-)

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Selection Filter vs. Btr Iterating
« Reply #7 on: January 30, 2011, 08:19:32 AM »
Actually, my guess is that Editor.SelectAll with a filter, iterates the database and uses AcRxObject::IsA()  to filter the set.  Selection sets should always be slightly slower than explicitly iterating

Which all the test I have done show exactly that with blocks or no blocks, unless searching for blockreferences then it is opposite Editor.SelectAll is faster


Why would this differ just BlockReferences?


Using the code below and changing to filter and add circles CenterPoint, Lines StartPoint iterating the ModelSpace BlockTableRecord was faster. For BlockReferences again SelectionFilter was faster 


kaefer

  • Guest
Re: Selection Filter vs. Btr Iterating
« Reply #8 on: January 30, 2011, 08:26:38 AM »
As the quotient of OWII/Total number of objects in BTR approaches zero, iterating takes ever more time relative to a SelectionSet.

why?

Good question, dan.

Iterating by GetObject with subsequent type test, that is. I did it Jeff's way; we're doing it wrong, aren't we? Testing ObjectId.ObjectClass is much faster, of  course.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8743
  • AKA Daniel
Re: Selection Filter vs. Btr Iterating
« Reply #9 on: January 30, 2011, 08:30:04 AM »
Testing ObjectId.ObjectClass is much faster

True that!!

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8743
  • AKA Daniel
Re: Selection Filter vs. Btr Iterating
« Reply #10 on: January 30, 2011, 08:42:01 AM »
I totally forgot about this method,  most of the code I write is 2007-2011 compatible.... :|

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Selection Filter vs. Btr Iterating
« Reply #11 on: January 30, 2011, 08:49:45 AM »
Thanks Thorsten and Daniel now it is quicker also for BlockReferences


Code: [Select]
foreach (ObjectId id in btr)
         {
             if (id.ObjectClass.Name == "AcDbBlockReference")
             {
               
                 BlockReference dbPnt = trx.GetObject(id, OpenMode.ForRead) as BlockReference;                 
                     
                     pntsIter.Add(dbPnt.Position);
             }
           
         }


Jeff H

  • Needs a day job
  • Posts: 6150
Re: Selection Filter vs. Btr Iterating
« Reply #12 on: January 30, 2011, 09:01:58 AM »
Daniel and Thorsten,

Would you recommend using something like this

Code: [Select]
if (ObjectId .ObjectClass.Name == "AcDbBlockReference")
             {               
                 // Do Whatever           
             }

if searching for a certain entity type?


Thanks again guys!

kaefer

  • Guest
Re: Selection Filter vs. Btr Iterating
« Reply #13 on: January 31, 2011, 04:18:39 AM »
Would you recommend using something like this

Code: [Select]
if (ObjectId .ObjectClass.Name == "AcDbBlockReference")
             {               
                 // Do Whatever           
             }

if searching for a certain entity type?

I'd rather use RXClass.IsDerivedFrom, like this example (borrowed from TT):
Code: [Select]
    {
        if( id.IsValid && id.ObjectClass.IsDerivedFrom( curveClass ) )
        { ... }
    }
    static RXClass curveClass = RXObject.GetClass( typeof( Curve ) );

As Dan already mentioned, this API wasn't around from the very beginning, but only since 17.2?.

All the best

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Selection Filter vs. Btr Iterating
« Reply #14 on: February 02, 2011, 12:55:29 PM »
Would you recommend using something like this

Code: [Select]
if (ObjectId .ObjectClass.Name == "AcDbBlockReference")
             {               
                 // Do Whatever           
             }

if searching for a certain entity type?

I'd rather use RXClass.IsDerivedFrom, like this example (borrowed from TT):
Code: [Select]
    {
        if( id.IsValid && id.ObjectClass.IsDerivedFrom( curveClass ) )
        { ... }
    }
    static RXClass curveClass = RXObject.GetClass( typeof( Curve ) );

As Dan already mentioned, this API wasn't around from the very beginning, but only since 17.2?.

All the best

Thanks again Thorsten