RTTI question

C

Chameleon

I know than dynamic_cast check string name of derived to base class and
if one of them match, return the pointer of that object or else zero.

I suppose, I dynamic_cast instead of strings, checks integers, then this
procedure will be more fast, so I create something like this:

---------------------------------------------
class A
{
public:
const static int RTTI = 0;
virtual bool checkRTTI(int rtti) { return RTTI == rtti; }
};

class B : public A
{
public:
const static int RTTI = 1;
virtual bool checkRTTI(int rtti) { return RTTI == rtti ||
A::checkRTTI(rtti); }
};

int main()
{
B b;
A *a = &b;
a->checkRTTI(B::RTTI);
return 0;
}
---------------------------------------------

I am curius why when I count the time to do this:
a->checkRTTI(B::RTTI)
I found it 5 times bigger than this:
dynamic_cast<B*>(a) ? true : false

I am offtopic? Compiler is mingw-g++

thanks!
 
R

Ron Natalie

Chameleon said:
I am curius why when I count the time to do this:
a->checkRTTI(B::RTTI)
I found it 5 times bigger than this:
dynamic_cast<B*>(a) ? true : false

I am offtopic? Compiler is mingw-g++
It probably is off topic...your answer for implementation
details is probably best asked in a group specific to
your compiler.

However, I suspect the major reason is that dynamic_cast
is very nicely inlined as the compiler knows just exactly
what you are doing. The "B*" is effectively constant
as the cast operand.

Virtual calls are (near) impossible to inline. It has
to emit code to pass the value B::RTTI and invoke the
virtual call.
 
L

Lance Diduck

Chameleon said:
I know than dynamic_cast check string name of derived to base class and
if one of them match, return the pointer of that object or else zero.

I suppose, I dynamic_cast instead of strings, checks integers, then this
procedure will be more fast, so I create something like this:

---------------------------------------------
class A
{
public:
const static int RTTI = 0;
virtual bool checkRTTI(int rtti) { return RTTI == rtti; }
};

class B : public A
{
public:
const static int RTTI = 1;
virtual bool checkRTTI(int rtti) { return RTTI == rtti ||
A::checkRTTI(rtti); }
};

int main()
{
B b;
A *a = &b;
a->checkRTTI(B::RTTI);
return 0;
}
---------------------------------------------

I am curius why when I count the time to do this:
a->checkRTTI(B::RTTI)
I found it 5 times bigger than this:
dynamic_cast<B*>(a) ? true : false

I am offtopic? Compiler is mingw-g++

thanks!
My understanding (without actually looking it up) is the standard does
not specify how a compiler is to implement dynamic_cast, just that if
you use dynamic_cast it should be on classes with at least one virtual
function. I surmise that strings are chosen 1) because class-to-string
already exists in the form of name mangling, so why repeat yourself?
and 2) That mapping a type to an integer is difficult at best when
using dynamically loaded modules, which doesnt even have to be compiled
by the same compiler.

COM implements a thing nearly the same as dynamic_cast, namely
QueryInterface, that does use integers. But if you really wanted a fast
lookup of dynamic_cast (which in many exception implementation is used
internally by the compiler to match an exception with a catch handler)
then there are hash tables that offer very fast lookups. Look at
implementations of exception handling --the Wiki page is a good
starting point.

Why is your example so much slower? Because the compiler already knows
at compiler time that a is really a B* , it is smart enough to follow
what you did and optimize. If a was initialized from a value that comes
from a different translation unit, then your results will vary.

But this goes to show that you can rarely optimize things without
actually running a profiler on it -- results are rarley if ever what
you expect.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top