Consider this benchmark:
import std.stdio, std.datetime;
class A{}
final class B:A{}
A x;
static this(){x=new B;}
B f1(){ return cast(B)x; }
T fastCast(T,R)(R x){return typeid(x) is typeid(T)?cast(T)cast(void*)x:null;}
B f2(){ return fastCast!(B)(x); }
void main() {
auto a=benchmark!(f1,f2)(1000000);
writeln(a[0].to!("seconds",double));
writeln(a[1].to!("seconds",double));
}
f2 is about 30x faster on my machine, compiled with dmd -O -release -inline. (DMD 2.054). If the benchmark is changed so that the cast does not succeed, the difference is even larger.
This means DMD should probably optimize downcasts to final classes to a simple typeid pointer comparison. That is safe, because final classes have no children.
Comment #1 by timon.gehr — 2011-09-06T16:44:26Z
hm, ok. It seems that druntime actually does shortcut and most of the difference boils down to the fact that the druntime function cannot be inlined...
Comment #2 by andrej.mitrovich — 2013-02-08T14:29:25Z
(In reply to comment #1)
> It seems that druntime actually does shortcut
Where in druntime is casting for classes defined btw? I assumed I would see an opCast function somewhere.
Comment #3 by bearophile_hugs — 2013-02-08T14:46:40Z
See also Issue 5559
Comment #4 by robert.schadek — 2024-12-13T17:56:23Z