C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

typeid() faster than dynamic_cast<>

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Jamie Burns
Guest





PostPosted: Tue Jan 27, 2004 8:50 pm    Post subject: typeid() faster than dynamic_cast<> Reply with quote



Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}

And the latter case blew the former out of the water. Using typeid() with a
C style cast was 94 times faster than using dynamic_cast<>.

So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?

Jamie Burns.


Back to top
Alf P. Steinbach
Guest





PostPosted: Tue Jan 27, 2004 9:01 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote



On Tue, 27 Jan 2004 20:50:02 -0000, "Jamie Burns" <sephana (AT) email (DOT) com> wrote:

Quote:
I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}

And the latter case blew the former out of the water. Using typeid() with a
C style cast was 94 times faster than using dynamic_cast<>.

In general this is a quality-of-implementation issue. A factor of 94
for this code seems excessive. To say the least.


Quote:
So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?

Assuming you meant to write 'static_cast', not 'C style cast', which you
should never use:

It depends. With dynamic_cast you allow a wider range of actual types for
'object' than you do with typeid. With typeid you tell the compiler that
you're only interested in one particular type, and so it can be faster,
as well as more specifically expressing the intent of the code.

Btw., why not use '++xx', and why not declare 'xx' in the loop?


Back to top
lilburne
Guest





PostPosted: Tue Jan 27, 2004 9:05 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote



Jamie Burns wrote:

Quote:

And the latter case blew the former out of the water. Using typeid() with a
C style cast was 94 times faster than using dynamic_cast<>.

So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?


What if rDerived is actually sDerived, which version is
correct then?


Back to top
Pete Becker
Guest





PostPosted: Tue Jan 27, 2004 10:12 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

Jamie Burns wrote:
Quote:

So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?


They do different things. When you compare typeids you're only making
one comparison. When you use dynamic_cast you're walking the inheritance
hierarchy looking for a type match. Of course, the benefit of the latter
is that it actually gets the right answer if you change your inheritance
hierarchy in various ways.

Using typeid is only "better" if you don't care how robust the code is
and you've determined that the type comparison is a bottleneck in your
application.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Back to top
Jonathan Turkanis
Guest





PostPosted: Tue Jan 27, 2004 10:44 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

"Jamie Burns" <sephana (AT) email (DOT) com> wrote

Quote:
Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}


I think you might be making a simple mistake. A pointer is not a
polymorphic type, so typeid(T*) returns a type_info object
representing the static pointer type T*. An expression of the form
typeid(rDerived*) returns a type_info object represent the type
rDerived*. Likewise, if 'object' is decalred:

Base* object;

then typeid(object) should return a type_info object representing the
type Base*.

The condition in the second loop can be evaluated partly at compile
time, since the static types are known. If 'object' is decalred as
above, the condition will never hold, and the function calls will be
skipped. Have you verified that the function setValue is actually
being called?

Jonathan





Back to top
David White
Guest





PostPosted: Tue Jan 27, 2004 11:08 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

"Jamie Burns" <sephana (AT) email (DOT) com> wrote

Quote:
Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}

And the latter case blew the former out of the water. Using typeid() with
a
C style cast was 94 times faster than using dynamic_cast<>.

In a similar benchmark using VC++ 7.0 optimized for speed, I found the
dynamic_cast version to take between 3 and 4 times as long as the typeid
version. This is not surprising considering what they each do, but a factor
of 94 is a surprise.

Quote:
So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?

No. They do different things. They are interchangeable only if there are no
classes derived from rDerived, or you want to ignore them (unlikely, since a
class derived from rDerived IS-A rDerived). Even if there are no classes
derived from rDerived now, there might be later, and you wouldn't want your
code to break. Unless you really need to squeeze every drop of speed out of
the machine, using typeid for this purpose is a bad move.

DW




Back to top
Andrey Tarasevich
Guest





PostPosted: Wed Jan 28, 2004 12:42 am    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

Jonathan Turkanis wrote:
Quote:
...
I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}


I think you might be making a simple mistake. A pointer is not a
polymorphic type, so typeid(T*) returns a type_info object
representing the static pointer type T*. An expression of the form
typeid(rDerived*) returns a type_info object represent the type
rDerived*. Likewise, if 'object' is decalred:

Base* object;

then typeid(object) should return a type_info object representing the
type Base*.
...

Nice catch. It appears that no one else noticed this. The second test
('typeid') does not do what OP intended it to do. The 'if' statement in
the second loop should look as follows

...
if (typeid(*object) == typeid(rDerived))
...

--
Best regards,
Andrey Tarasevich


Back to top
Pete Becker
Guest





PostPosted: Wed Jan 28, 2004 12:59 am    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

Andrey Tarasevich wrote:
Quote:

Jonathan Turkanis wrote:
...
I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast if (derived) derived->setValue(message.data.messageSetInt.value);
}

against:

for (xx=0;xx<100000;xx++) {
if (typeid(object) == typeid(rDerived*)) ((rDerived*)
object)->setValue(message.data.messageSetInt.value);
}


I think you might be making a simple mistake. A pointer is not a
polymorphic type, so typeid(T*) returns a type_info object
representing the static pointer type T*. An expression of the form
typeid(rDerived*) returns a type_info object represent the type
rDerived*. Likewise, if 'object' is decalred:

Base* object;

then typeid(object) should return a type_info object representing the
type Base*.
...

Nice catch. It appears that no one else noticed this. The second test
('typeid') does not do what OP intended it to do. The 'if' statement in
the second loop should look as follows

...
if (typeid(*object) == typeid(rDerived))
...


Of course, given the number of typos in the "code", it's not really
possible to tell whether that's what he did.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Back to top
Hendrik Belitz
Guest





PostPosted: Wed Jan 28, 2004 8:14 am    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

Jamie Burns wrote:

Quote:
So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?

The best way is not to use that stuff at all. Ask yourself if your software
design is really good. Most of the time using the RTTI functionality is
only a hint to a bad program design. AFAIK there is only one useful
application of RTTI, and that's emulating weak typing in C++.

--
To get my real email adress, remove the two onkas
--
Dipl.-Inform. Hendrik Belitz
Central Institute of Electronics
Research Center Juelich

Back to top
lilburne
Guest





PostPosted: Wed Jan 28, 2004 9:24 am    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote



Hendrik Belitz wrote:
Quote:
Jamie Burns wrote:


So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?


The best way is not to use that stuff at all. Ask yourself if your software
design is really good. Most of the time using the RTTI functionality is
only a hint to a bad program design. AFAIK there is only one useful
application of RTTI, and that's emulating weak typing in C++.


Not quite! Lets say I have a class Curve and derived classes
representing line, circular arc, bezier, nurb, composites. And given two
Curves I want to find the points where they intersect. Now I can write
a general method for this, but if I know (RTTI) that the both entities
are lines, or both are arcs, then I can provide a more efficent solution
for these special cases.


Back to top
Klaus Nowikow
Guest





PostPosted: Wed Jan 28, 2004 9:52 am    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote

Hendrik Belitz wrote:
Quote:
Jamie Burns wrote:


So is it really better to use typeid() and a C style cast rather than the
(apparantly) slower dynamic_cast<>?


The best way is not to use that stuff at all. Ask yourself if your software
design is really good. Most of the time using the RTTI functionality is
only a hint to a bad program design. AFAIK there is only one useful
application of RTTI, and that's emulating weak typing in C++.

Well, I don't think dynamic_cast<>ing from one abstract base class
to another abstract base class (interface) is the bad thing.
It's the _downcast_ that shows poor class design.

--
Klaus


Back to top
Nick Hounsome
Guest





PostPosted: Thu Jan 29, 2004 8:54 pm    Post subject: Re: typeid() faster than dynamic_cast<> Reply with quote


"lilburne" <lilburne (AT) godzilla (DOT) com> wrote

Quote:


Hendrik Belitz wrote:
Jamie Burns wrote:


So is it really better to use typeid() and a C style cast rather than
the
(apparantly) slower dynamic_cast


The best way is not to use that stuff at all. Ask yourself if your
software
design is really good. Most of the time using the RTTI functionality is
only a hint to a bad program design. AFAIK there is only one useful
application of RTTI, and that's emulating weak typing in C++.


Not quite! Lets say I have a class Curve and derived classes
representing line, circular arc, bezier, nurb, composites. And given two
Curves I want to find the points where they intersect. Now I can write
a general method for this, but if I know (RTTI) that the both entities
are lines, or both are arcs, then I can provide a more efficent solution
for these special cases.


How about double dispatch - if you're hierarchy is fixed then this is the
cleanest way.

class Curve
{
protected:
// derived classes override these with efficient impl
virtual XXX intersect2(const Line&) const = 0;
virtual XXX intersect2(const Bezier&) const = 0;
//etc etc
public:
// all the derived classes implement intersect EXACTLY the same
virtual XXX intersect(const Curve& other) const
{
return other.intersect2(*this);
}
};

class Bezier : public Curve { .....}
etc

Bezier bez;
Line line;
Curve& c1 = bez;
Curve& c2 = line;
c1.intersect(c2);
calls Bezier::intersect(const Curve&)
calls Line::intersect2(const Bezier&)
does efficient intersection



Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.