digitalmars.D.learn - Properties set/get huge speed difference?
- ephemeros (68/68) Sep 15 2006 Hello,
- Unknown W. Brackets (4/88) Sep 15 2006 Try defining the getter and setter as final.
- ephemeros (2/10) Sep 16 2006 i tried, there is no notable difference. :(
- Dave (2/13) Sep 16 2006 DMD does inline inter-module 'final'.
- ephemeros (5/19) Sep 16 2006 although the program compiled with dmd is slower (0.20s) than gdc, this
- %u (2/5) Oct 09 2006 I thought D was supposed to automatically make all methods final that ar...
- Lars Ivar Igesund (7/14) Oct 09 2006 How could the compiler know that? The class might be put into a library,...
- Sean Kelly (21/32) Oct 09 2006 I think it's more likely that a compiler may optimize function calls
- Josh Stern (4/19) Oct 09 2006 I had all the same thoughts. For all these reasons, wouldn't it be a go...
- Sean Kelly (7/29) Oct 09 2006 Hrm... perhaps I'm misunderstanding, but don't they already exist?
- Josh Stern (6/19) Oct 09 2006 Excellent! I knew it *should* be there, but I got thrown off by the docs
Hello, anyone knows why getting/setting the class properties by invoking the methods is so slow (~20 times slower - gdc/ubuntu/amd32) comparing with doing the same things directly, with the "=" operator (public properties)? this matters in an app with thousands of evaluations per loop, also the methods are needed to compose different behaviors, etc. i give here a little "get" example: //======================= // src/clasamare.d module src.clasamare; class ClasaMare { //private: float val; //public: void value(float newValue) { val=newValue; } float value() { return val; } } //========================= this runs slower(~0.450s): //========================= // src/test.d import src.clasamare; import std.cstream; int main() { ClasaMare cls1=new ClasaMare(); for(uint i=0; i<100000000; i++) { cls1.value=15.7; } dout.writefln("%f", cls1.value); return 0; } //========================== this is faster(~0.020s): //========================= // src/test.d import src.clasamare; import std.cstream; int main() { ClasaMare cls1=new ClasaMare(); for(uint i=0; i<100000000; i++) { cls1.val=15.7; } dout.writefln("%f", cls1.value); return 0; } //========================== i compiled with this command: gdc -frelease -s -O3 -fomit-frame-pointer -mmmx -msse -mfpmath=sse -mfancy-math-387 -minline-all-stringops -fschedule-insns2 -frerun-loop-opt -frerun-cse-after-loop -funroll-loops -fexpensive-optimizations -finline-functions -o made test.d src/clasamica.d src/clasamare.d when i compile with: gdmd -O -release -inline test.d src/clasamica.d src/clasamare.d the times are 0.450s/0.150s thank you
Sep 15 2006
Try defining the getter and setter as final. It's a function call, and it's using a virtual table as far as I know. That's going to be a lot slower. -[Unknown]Hello, anyone knows why getting/setting the class properties by invoking the methods is so slow (~20 times slower - gdc/ubuntu/amd32) comparing with doing the same things directly, with the "=" operator (public properties)? this matters in an app with thousands of evaluations per loop, also the methods are needed to compose different behaviors, etc. i give here a little "get" example: //======================= // src/clasamare.d module src.clasamare; class ClasaMare { //private: float val; //public: void value(float newValue) { val=newValue; } float value() { return val; } } //========================= this runs slower(~0.450s): //========================= // src/test.d import src.clasamare; import std.cstream; int main() { ClasaMare cls1=new ClasaMare(); for(uint i=0; i<100000000; i++) { cls1.value=15.7; } dout.writefln("%f", cls1.value); return 0; } //========================== this is faster(~0.020s): //========================= // src/test.d import src.clasamare; import std.cstream; int main() { ClasaMare cls1=new ClasaMare(); for(uint i=0; i<100000000; i++) { cls1.val=15.7; } dout.writefln("%f", cls1.value); return 0; } //========================== i compiled with this command: gdc -frelease -s -O3 -fomit-frame-pointer -mmmx -msse -mfpmath=sse -mfancy-math-387 -minline-all-stringops -fschedule-insns2 -frerun-loop-opt -frerun-cse-after-loop -funroll-loops -fexpensive-optimizations -finline-functions -o made test.d src/clasamica.d src/clasamare.d when i compile with: gdmd -O -release -inline test.d src/clasamica.d src/clasamare.d the times are 0.450s/0.150s thank you
Sep 15 2006
Unknown W. Brackets wrote:Try defining the getter and setter as final. It's a function call, and it's using a virtual table as far as I know. That's going to be a lot slower. -[Unknown]i tried, there is no notable difference. :(
Sep 16 2006
ephemeros wrote:Unknown W. Brackets wrote:DMD does inline inter-module 'final'.Try defining the getter and setter as final. It's a function call, and it's using a virtual table as far as I know. That's going to be a lot slower. -[Unknown]i tried, there is no notable difference. :(
Sep 16 2006
Dave wrote:ephemeros wrote:although the program compiled with dmd is slower (0.20s) than gdc, this doesn't concern me now. "final" works in dmd, both gets/sets have the same speed. thanks guys!Unknown W. Brackets wrote:DMD does inline inter-module 'final'.Try defining the getter and setter as final. It's a function call, and it's using a virtual table as far as I know. That's going to be a lot slower. -[Unknown]i tried, there is no notable difference. :(
Sep 16 2006
although the program compiled with dmd is slower (0.20s) than gdc, this doesn't concern me now. "final" works in dmd, both gets/sets have the same speed.I thought D was supposed to automatically make all methods final that aren't changed by a subclass?
Oct 09 2006
%u wrote:How could the compiler know that? The class might be put into a library, and subclassed in an application (a very common use case) or other library. -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivialthough the program compiled with dmd is slower (0.20s) than gdc, this doesn't concern me now. "final" works in dmd, both gets/sets have the same speed.I thought D was supposed to automatically make all methods final that aren't changed by a subclass?
Oct 09 2006
Lars Ivar Igesund wrote:%u wrote:I think it's more likely that a compiler may optimize function calls when it knows exactly what type of object is being called. For example: class C { void doSomething() {} } void main() { C c = new C(); c.doSomething(); // A } In the code above, even though a vtbl entry may be generated for doSomething, the compiler may optimize the call at point A by calling C.doSomething directly instead of using a double lookup through C's vtbl. This can be accomplished because the compiler knows that c must be an instance of C at the call point (thus making the optimization extensible to more complex cases where doSomething really is a virtual function). I'm not sure if DMD currently performs this optimization however, but my guess would be that it does not. It's still more important to make DMD as bug-free as possible than it is to optimize corner-cases. SeanHow could the compiler know that? The class might be put into a library, and subclassed in an application (a very common use case) or other library.although the program compiled with dmd is slower (0.20s) than gdc, this doesn't concern me now. "final" works in dmd, both gets/sets have the same speed.I thought D was supposed to automatically make all methods final that aren't changed by a subclass?
Oct 09 2006
On Mon, 09 Oct 2006 12:20:36 -0700, Sean Kelly wrote:void main() { C c = new C(); c.doSomething(); // A } In the code above, even though a vtbl entry may be generated for doSomething, the compiler may optimize the call at point A by calling C.doSomething directly instead of using a double lookup through C's vtbl. This can be accomplished because the compiler knows that c must be an instance of C at the call point (thus making the optimization extensible to more complex cases where doSomething really is a virtual function). I'm not sure if DMD currently performs this optimization however, but my guess would be that it does not. It's still more important to make DMD as bug-free as possible than it is to optimize corner-cases.I had all the same thoughts. For all these reasons, wouldn't it be a good idea to add "final" methods to the language to give the developer the necessary tool to optimize this intelligently if they need it?
Oct 09 2006
Josh Stern wrote:On Mon, 09 Oct 2006 12:20:36 -0700, Sean Kelly wrote:Hrm... perhaps I'm misunderstanding, but don't they already exist? class C { final void doSomething() {} } 'final' guarantees that C.doSomething above will not have a vtbl entry. Seanvoid main() { C c = new C(); c.doSomething(); // A } In the code above, even though a vtbl entry may be generated for doSomething, the compiler may optimize the call at point A by calling C.doSomething directly instead of using a double lookup through C's vtbl. This can be accomplished because the compiler knows that c must be an instance of C at the call point (thus making the optimization extensible to more complex cases where doSomething really is a virtual function). I'm not sure if DMD currently performs this optimization however, but my guess would be that it does not. It's still more important to make DMD as bug-free as possible than it is to optimize corner-cases.I had all the same thoughts. For all these reasons, wouldn't it be a good idea to add "final" methods to the language to give the developer the necessary tool to optimize this intelligently if they need it?
Oct 09 2006
On Mon, 09 Oct 2006 16:22:13 -0700, Sean Kelly wrote:Josh Stern wrote:On Mon, 09 Oct 2006 12:20:36 -0700, Sean Kelly wrote:Excellent! I knew it *should* be there, but I got thrown off by the docs when it isn't mentioned on the "class" page and the first paragraph on the "function" page says that all member functions are virtual because the compiler can figure out if they really need to be (though we just discussed why that isn't true).I had all the same thoughts. For all these reasons, wouldn't it be a good idea to add "final" methods to the language to give the developer the necessary tool to optimize this intelligently if they need it?Hrm... perhaps I'm misunderstanding, but don't they already exist? class C { final void doSomething() {} } 'final' guarantees that C.doSomething above will not have a vtbl entry.
Oct 09 2006