473,419 Members | 1,704 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,419 software developers and data experts.

typeid() faster than dynamic_cast<>

Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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.
Jul 22 '05 #1
11 3284
On Tue, 27 Jan 2004 20:50:02 -0000, "Jamie Burns" <se*****@email.com> wrote:
I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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.

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?

Jul 22 '05 #2
Jamie Burns wrote:

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?

Jul 22 '05 #3
Jamie Burns wrote:

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)
Jul 22 '05 #4
"Jamie Burns" <se*****@email.com> wrote in message
news:bv*******************@news.demon.co.uk...
Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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


Jul 22 '05 #5
"Jamie Burns" <se*****@email.com> wrote in message
news:bv*******************@news.demon.co.uk...
Hello,

I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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.
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

Jul 22 '05 #6
Jonathan Turkanis wrote:
...
I just did a simple benchmark:

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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

Jul 22 '05 #7
Andrey Tarasevich wrote:

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

for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
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)
Jul 22 '05 #8
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++.

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


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.

Jul 22 '05 #10
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++.


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

Jul 22 '05 #11

"lilburne" <li******@godzilla.com> wrote in message
news:bv************@ID-179504.news.uni-berlin.de...


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
Jul 22 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: alg | last post by:
dynamic_cast<> comes in play when to perform conversion from a pointer to a base class to a pointer to a derived class. I don't understand: 1. why this is so necessary since we can either use...
15
by: Grizlyk | last post by:
Hello. Returning to question of manual class type identification, tell me, for ordinary inheritance is C++ garantee that dynamic_cast<Derived*>(Base*) can be implemented similarly to ...
13
by: baltasarq | last post by:
Hi, there ! When I use dynamic_cast for a single object, I do something like: void foo(Base *base) { if ( dynamic_cast<Derived *>( base ) != NULL ) { ((Derived *) base)->do_something() } }
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.