www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - how to determine a runtime type faster?

reply davidl <davidl 126.com> writes:
module funky.super.meaningless.modulename;
class base
{
}
class derive:base
{
}
void main()
{
     derive instance=3D new derive;
     base castedinstance=3Dinstance;
     // notice the following would result a super long string comparisio=
n ,  =

which is not so good.
     //  =

`funky.super.meaningless.modulename.derive`=3D=3D`funky.super.meaningles=
s.modulename.derive`
     assert(castedinstance.classinfo.name=3D=3Dderive.classinfo.name);

}
the idea is castedinstance.classinfo.runtimeid?
the runtimeid could generated by the compiler and with some proper desig=
n  =

about object.d , i think
the comparision could be faster
May 10 2007
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
davidl wrote:
 module funky.super.meaningless.modulename;
 class base
 {
 }
 class derive:base
 {
 }
 void main()
 {
     derive instance= new derive;
     base castedinstance=instance;
     // notice the following would result a super long string comparision
 , which is not so good.
     //
 `funky.super.meaningless.modulename.derive`==`funky.super.meaningless.modulename.derive`
 
     assert(castedinstance.classinfo.name==derive.classinfo.name);
 
 }
 the idea is castedinstance.classinfo.runtimeid?
 the runtimeid could generated by the compiler and with some proper
 design about object.d , i think
 the comparision could be faster
Have you tried comparing the classinfo directly? I have a feeling they should be the same for every instance of a particular class... -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 10 2007
parent davidl <davidl 126.com> writes:
great ur way does work

 davidl wrote:
 module funky.super.meaningless.modulename;
 class base
 {
 }
 class derive:base
 {
 }
 void main()
 {
     derive instance= new derive;
     base castedinstance=instance;
     // notice the following would result a super long string comparision
 , which is not so good.
     //
 `funky.super.meaningless.modulename.derive`==`funky.super.meaningless.modulename.derive`

     assert(castedinstance.classinfo.name==derive.classinfo.name);

 }
 the idea is castedinstance.classinfo.runtimeid?
 the runtimeid could generated by the compiler and with some proper
 design about object.d , i think
 the comparision could be faster
Have you tried comparing the classinfo directly? I have a feeling they should be the same for every instance of a particular class... -- Daniel
-- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
May 10 2007
prev sibling parent reply "Vladimir Panteleev" <thecybershadow gmail.com> writes:
On Thu, 10 May 2007 16:16:42 +0300, davidl <davidl 126.com> wrote:

 module funky.super.meaningless.modulename;
 class base
 {
 }
 class derive:base
 {
 }
 void main()
 {
      derive instance=3D new derive;
      base castedinstance=3Dinstance;
      // notice the following would result a super long string comparis=
ion ,
 which is not so good.
      //
 `funky.super.meaningless.modulename.derive`=3D=3D`funky.super.meaningl=
ess.modulename.derive`
      assert(castedinstance.classinfo.name=3D=3Dderive.classinfo.name);=
 }
 the idea is castedinstance.classinfo.runtimeid?
 the runtimeid could generated by the compiler and with some proper des=
ign
 about object.d , i think
 the comparision could be faster
From http://www.digitalmars.com/d/expression.html#CastExpression :
 Any casting of a class reference to a derived class reference is done =
with a runtimecheck to make sure it really is a downcast. null is the re= sult if it isn't. Note: Thisis equivalent to the behavior of the dynamic= _cast operator in C++. So, for your example you only need: assert(cast(derive)castedinstance); -- = Best regards, Vladimir mailto:thecybershadow gmail.com
May 10 2007
parent reply davidl <davidl 126.com> writes:
umm , ur way rox either. but i don't know if the cast(derive)instance is  
implemented as good as
(instance.classinfo is derive.classinfo)?

 On Thu, 10 May 2007 16:16:42 +0300, davidl <davidl 126.com> wrote:

 module funky.super.meaningless.modulename;
 class base
 {
 }
 class derive:base
 {
 }
 void main()
 {
      derive instance= new derive;
      base castedinstance=instance;
      // notice the following would result a super long string  
 comparision ,
 which is not so good.
      //
 `funky.super.meaningless.modulename.derive`==`funky.super.meaningless.modulename.derive`
      assert(castedinstance.classinfo.name==derive.classinfo.name);

 }
 the idea is castedinstance.classinfo.runtimeid?
 the runtimeid could generated by the compiler and with some proper  
 design
 about object.d , i think
 the comparision could be faster
From http://www.digitalmars.com/d/expression.html#CastExpression :
 Any casting of a class reference to a derived class reference is done  
 with a runtimecheck to make sure it really is a downcast. null is the  
 result if it isn't. Note: Thisis equivalent to the behavior of the  
 dynamic_cast operator in C++.
So, for your example you only need: assert(cast(derive)castedinstance);
-- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
May 10 2007
next sibling parent reply BCS <BCS pathlink.com> writes:
davidl wrote:
 umm , ur way rox either. but i don't know if the cast(derive)instance 
 is  implemented as good as
 (instance.classinfo is derive.classinfo)?
 
another issue: class A{} class B:A{} class C:B{} A a = new C; assert(cast(B)a !is null); // passes The strongest and fastest check might be to compare the vtbl pointers. It will be a hack but it will be fast.
May 10 2007
parent davidl <davidl 126.com> writes:
weird, I tested it , it didn't pass last night :o
but this cast feature is exactly what I want.
The frontend source does require the feature u pointed out.
I tried to find one could walk through the heirarchy. And
D does rock! now all frontend's DYNCAST can be deprecated!!

 davidl wrote:
 umm , ur way rox either. but i don't know if the cast(derive)instance  
 is  implemented as good as
 (instance.classinfo is derive.classinfo)?
another issue: class A{} class B:A{} class C:B{} A a = new C; assert(cast(B)a !is null); // passes The strongest and fastest check might be to compare the vtbl pointers. It will be a hack but it will be fast.
-- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
May 10 2007
prev sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
davidl wrote:
 umm , ur way rox either. but i don't know if the cast(derive)instance is
 implemented as good as
 (instance.classinfo is derive.classinfo)?
I have a suspicion that casting is slower. The reason is that casting doesn't simply compare the types; it has to actually walk the object's inheritance tree. The advantage to using cast is that... it walks an object's inheritance tree. Using (instance.classinfo is derive.classinfo) will NOT work if the type of "instance" is derived from the base type. For instance: class A {} class B : A {} assert((new A).classinfo is (new B).classinfo); The above will fail. You should *only* directly compare them if you really, really, REALLY need the performance, and you've actually profiled your program to *prove* that, and you do not use inheritance at all. In all other cases, you should use a cast. The only reason I didn't suggest that in the first place is because I'm an idiot, and tried addressing your immediate problem (the string compare) instead of the underlying problem (checking for an instance of something). -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 10 2007