Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > dynamic_cast expensive?

Reply
Thread Tools

dynamic_cast expensive?

 
 
cppquester
Guest
Posts: n/a
 
      04-24-2010
When I replaced the dynamic cast in the code excerpt below
(here each class knows it type), I gained a speedup of about factor
4(!)
(in release mode (-O2))

Why is a dynamic cast so expensive? I thought basically the RTTI
system basically does
what I did (store the type (implicitely) and then cast or return
NULL).

Or might this be specific to my platform (g++ 4.2.4)?

Thanks,
Marc


thisType* lEnd=dynamic_cast<thisType*>(derived);
if( lEnd == NULL)
throw MyException("Type changed.");*/


if( derived->Type() != this->type)
throw MyException("Type changed.");
thisType* lEnd=static_cast<thisType*>(derived);


 
Reply With Quote
 
 
 
 
Martijn van Buul
Guest
Posts: n/a
 
      04-24-2010
* cppquester:
> When I replaced the dynamic cast in the code excerpt below
> (here each class knows it type), I gained a speedup of about factor
> 4(!)
> (in release mode (-O2))
>
> Why is a dynamic cast so expensive? I thought basically the RTTI
> system basically does
> what I did (store the type (implicitely) and then cast or return
> NULL).


No, that's not what it does. Your alternative code suggests that you
think that a dynamic_cast<T> will fail if the supplied pointer is not
pointing at an instance of type T. It's slightly more complex than
that.

Consider the following example:

class object { ... };

class rectangle : public object { ... };

class square : public rectangle { ... };

square mySquare;
object* squarePtr = &mySquare;

Both the dynamic cast and your approach will work for a cast to square*.
However, yours will *fail* for a cast to rectangle*, whereas the
dynamic_cast<> will work. Things get increasingly complex if you take
multiple inheritance into consideration. Either way, dynamic_cast<> may have
to traverse the entire inheritance tree in order to determine success or
failure, and this may indeed turn out to be expensive - especially if you
have a significant amount of classes derived from a common base class.

Bottom line: Your Type() based approach will only work for *exact* matches,
not for casts to an intermediate base class.

> Or might this be specific to my platform (g++ 4.2.4)?


No.

> thisType* lEnd=dynamic_cast<thisType*>(derived);
> if( lEnd == NULL)
> throw MyException("Type changed.");*/


This also means that the above test is possibly flawed. It wouldn't
generate an exception in case 'derived' points to an object that is
-derived- from thisType (but not a thisType itself). Your choice of
variable names is slightly confusing, so I'm not really sure that's
what you want.

> if( derived->Type() != this->type)
> throw MyException("Type changed.");
> thisType* lEnd=static_cast<thisType*>(derived);


You coud use a typeid() keyword for a more standard approach; something
along the line of

if (std::typeid(derived) != std::typeid(type))
...

Note that there's a performance issue lurking here too; while
std::typeid() is constant order (as opposed to dynamic_cast<>), comparing
the std::type_info resulting from the calls to std::typeid() may be
expensive. While it is implementation-defined, it'll most likely contain
the typename as a (not necessarily human-readable) string, which makes
comparison not cheap either.

There are a few workarounds floating around, using pointers to
std::type_info instead, but that smells like undefined behaviour. I know
from own experience that this trick will most likely not work for libraries.

--
Martijn van Buul - http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Salt_Peter
Guest
Posts: n/a
 
      04-24-2010
On Apr 24, 12:16*pm, cppquester <(E-Mail Removed)> wrote:
> When I replaced the dynamic cast in the code excerpt below
> (here each class knows it type), I gained a speedup of about factor
> 4(!)
> (in release mode (-O2))
>
> Why is a dynamic cast so expensive? I thought basically the RTTI
> system basically does
> what I did (store the type (implicitely) and then cast or return
> NULL).
>
> Or might this be specific to my platform (g++ 4.2.4)?
>
> Thanks,
> Marc
>
> * thisType* lEnd=dynamic_cast<thisType*>(derived);
> * if( lEnd == NULL)
> * * throw MyException("Type changed.");*/
>
> * if( derived->Type() != this->type)
> * * throw MyException("Type changed.");
> * thisType* lEnd=static_cast<thisType*>(derived);


Not enough info.
A class always knows its type, you don't need RTTI for that. In the
case where the object 'derived' above is of a type which is a
derivative of thisType, then derived will always be of type thisType.
So doing a dynamic cast is pointless, doing any cast is pointless.

So to answer your question: the question is irrelevant.

Btw, C++ programmers are reknown to be pathetic when it comes to
guessing. Try making a simple, short compileable example to explain
what you seek.

class thisType { };
class Derived : public thisType { };

int main()
{
// do stuff
}

 
Reply With Quote
 
cppquester
Guest
Posts: n/a
 
      04-25-2010
On 24 Apr., 21:25, Salt_Peter <(E-Mail Removed)> wrote:
> On Apr 24, 12:16*pm, cppquester <(E-Mail Removed)> wrote:
>
>
>
> > When I replaced the dynamic cast in the code excerpt below
> > (here each class knows it type), I gained a speedup of about factor
> > 4(!)
> > (in release mode (-O2))

>
> > Why is a dynamic cast so expensive? I thought basically the RTTI
> > system basically does
> > what I did (store the type (implicitely) and then cast or return
> > NULL).

>
> > Or might this be specific to my platform (g++ 4.2.4)?

>
> > Thanks,
> > Marc

>
> > * thisType* lEnd=dynamic_cast<thisType*>(derived);
> > * if( lEnd == NULL)
> > * * throw MyException("Type changed.");*/

>
> > * if( derived->Type() != this->type)
> > * * throw MyException("Type changed.");
> > * thisType* lEnd=static_cast<thisType*>(derived);

>
> Not enough info.
> A class always knows its type, you don't need RTTI for that. In the
> case where the object 'derived' above is of a type which is a
> derivative of thisType, then derived will always be of type thisType.
> So doing a dynamic cast is pointless, doing any cast is pointless.
>
> So to answer your question: the question is irrelevant.
>
> Btw, C++ programmers are reknown to be pathetic when it comes to
> guessing. Try making a simple, short compileable example to explain
> what you seek.
>
> class thisType { };
> class Derived : public thisType { };
>
> int main()
> {
> * // do stuff
>
> }
>
>



You are right, it was not clear.
Actually the following was meant:

class Base { virtual int Type(); ...};

class thisType: public Base { int t; int Type(){ return t;} ...};
class Derived : public Base { int t; int Type(){ return t;} ...};




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
typeid and dynamic_cast, gcc 3.3 Andreas Sch. C++ 18 01-29-2004 10:24 PM
typeid() faster than dynamic_cast<> Jamie Burns C++ 11 01-29-2004 08:54 PM
how static_cast and dynamic_cast implemented? Yuming Ma C++ 1 12-17-2003 12:58 AM
dynamic_cast and references Dan Noland C++ 0 07-29-2003 09:43 PM
dynamic_cast<> alg C++ 3 07-14-2003 09:08 AM



Advertisments