TheSwamp

Code Red => .NET => Topic started by: Jeff H on January 29, 2011, 09:59:18 PM

Title: Selection Filter vs. Btr Iterating
Post by: Jeff H 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 (http://www.theswamp.org/index.php?action=dlattach;topic=32874.0;attach=15396) from this Post (http://www.theswamp.org/index.php?topic=36818.msg418900#msg418900)


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();
   
     }
 }
Title: Re: Selection Filter vs. Btr Iterating
Post by: It's Alive! on January 30, 2011, 06:19:51 AM
see this thread http://www.theswamp.org/index.php?topic=21930.0
Title: Re: Selection Filter vs. Btr Iterating
Post by: Jeff H on January 30, 2011, 06:41:59 AM
see this thread http://www.theswamp.org/index.php?topic=21930.0

DOH!

I put selectionfilter in search

Sorry
Title: Re: Selection Filter vs. Btr Iterating
Post by: Kerry 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 ?
Title: Re: Selection Filter vs. Btr Iterating
Post by: kaefer 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
Title: Re: Selection Filter vs. Btr Iterating
Post by: It's Alive! 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?
Title: Re: Selection Filter vs. Btr Iterating
Post by: It's Alive! 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  :-)
Title: Re: Selection Filter vs. Btr Iterating
Post by: Jeff H 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 

Title: Re: Selection Filter vs. Btr Iterating
Post by: kaefer 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.
Title: Re: Selection Filter vs. Btr Iterating
Post by: It's Alive! on January 30, 2011, 08:30:04 AM
Testing ObjectId.ObjectClass is much faster

True that!!
Title: Re: Selection Filter vs. Btr Iterating
Post by: It's Alive! on January 30, 2011, 08:42:01 AM
I totally forgot about this method,  most of the code I write is 2007-2011 compatible.... :|
Title: Re: Selection Filter vs. Btr Iterating
Post by: Jeff H 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);
             }
           
         }

Title: Re: Selection Filter vs. Btr Iterating
Post by: Jeff H 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!
Title: Re: Selection Filter vs. Btr Iterating
Post by: kaefer 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
Title: Re: Selection Filter vs. Btr Iterating
Post by: Jeff H 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