What is the best way to find the type of an entity
-
I have seen .typename, .is_a?, and .class. Are there any other/better ways to refer to type?
-
There is also .kind_of?
There is a thread from a month or two ago that went into some detail. I think the main finding was that .typename is the worst option, and the others were all pretty comparable. Since that thread, I've been using .is_a? personally. Thom or Alex might know more about the details of it though,
Chris
-
hmm .typename works fine for me. Have'nt got much expierence with the other suggested methods though
-
it was shown that the .typanem is something around 10 times slower. So over thousands of entities, it really becomes noticeable. It was my method of choice. So what I used to write as:
if my_ent.typename == "Edge"
now I write as
if my_ent.is_a? Sketchup::Edge
I think typename is so slow because it is taking the object class (Sketchup::Edge) and converting it to a string, and parsing that string, and returning a string of "Edge". Whereas is_a? just returns the object class. So it does no class to string conversion and no parsing. I wonder what the difference is between .is_a? and .class
Chris
-
is_a?
(which is strictly synonym tokind_of?
) checks the class and superclasses.So if you have a component instance
comp
, then
comp.is_a? Sketchup::ComponentInstance
==> true
comp.is_a? Sketchup::Entity
==> trueWhich means that
is_a?
do some recursive checks on class hierarchy.Therefore, if you are sure of the class you test, then a statement like
comp.class == Sketchup::ComponentInstance
would be a little bit faster.Fredo
-
@unknownuser said:
is_a?
(which is strictly synonym tokind_of?
) checks the class and superclasses.So if you have a component instance
comp
, then
comp.is_a? Sketchup::ComponentInstance
==> true
comp.is_a? Sketchup::Entity
==> trueWhich means that
is_a?
do some recursive checks on class hierarchy.Therefore, if you are sure of the class you test, then a statement like
comp.class == Sketchup::ComponentInstance
would be a little bit faster.Fredo
Well explained.
The only time you need to use.typename
is to identify dimensions, 3dpolylines and other entities lacking proper API support and is presented with the genericDrawingElement
class. If you need to check for these types in a collection first check that it's a class ofDrawingElement
.if e.class == Sketchup::DrawingElement && e.typename == 'LinearDimension'
This will use the quick.class
method to filter out all the other entity types and only use the slower.typename
when really needed.AlexMogz did a very nice test script: http://forums.sketchucation.com/viewtopic.php?f=180&t=19576&st=0&sk=t&sd=a#p162235
Only thing is that you can see that other factors affect the results. As.is_a?
and.kind_of?
is aliases they should yield identical result. Later in that thread I did some larger test sets. -
The method instance_of? does not check agaisnt the superclasses the way kind_of? does. So it's probably faster, and certainly more specific. CB.
-
@daiku said:
The method instance_of? does not check agaisnt the superclasses the way kind_of? does. So it's probably faster, and certainly more specific. CB.
It's the same as
entity.class == Sketchup::Entity
-
@thomthom said:
It's the same as
entity.class == Sketchup::Entity
Apparently not.
instance_of?
seems to be 30% faster than.class ==
Now, we should not worry too much. In the Ruby console, a million call to the two methods consistently gives a 0.44 s forinstance_of?
and 0.65 for.class ==
.Fredo
-
hm... I was looking at the source code:
VALUE rb_obj_is_instance_of(obj, c) VALUE obj, c; { switch (TYPE(c)) { case T_MODULE; case T_CLASS; case T_ICLASS; break; default; rb_raise(rb_eTypeError, "class or module required"); } if (rb_obj_class(obj) == c) return Qtrue; return Qfalse; }
Could be that the compiled comparison runs faster - than doing it via Ruby. Didn't expect to be that much. Interesting.
-
@thomthom said:
Could be that the compiled comparison runs faster - than doing it via Ruby. Didn't expect to be that much. Interesting.
Yes, a call to a compiled function, even with many lines of code, is usually faster than a single Ruby statement (which needs parsing and execution).
This is why it is recommended to use the Geom functions for geometry calculations and avoid doing too much in Ruby. -
Think I need to look over my scripts again. Review the ruby code.
Advertisement