Jump to page: 1 2
Thread overview
Properties set/get huge speed difference?
Sep 16, 2006
ephemeros
Sep 16, 2006
ephemeros
Sep 16, 2006
Dave
Sep 17, 2006
ephemeros
Oct 09, 2006
%u
Oct 09, 2006
Lars Ivar Igesund
Oct 09, 2006
Sean Kelly
Oct 09, 2006
Josh Stern
Oct 09, 2006
Sean Kelly
Oct 10, 2006
Josh Stern
September 16, 2006
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
September 16, 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
September 16, 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. :(
September 16, 2006
ephemeros wrote:
> 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. :(

DMD does inline inter-module 'final'.
September 17, 2006
Dave wrote:
> ephemeros wrote:
>> 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. :(
> 
> DMD does inline inter-module 'final'.

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!
October 09, 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?
October 09, 2006
%u 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.
> 
> 
> I thought D was supposed to automatically make all methods final that aren't changed by a subclass?

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: larsivi
October 09, 2006
Lars Ivar Igesund wrote:
> %u 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.
>>
>> I thought D was supposed to automatically make all methods final that
>> aren't changed by a subclass?
> 
> 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.

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.


Sean
October 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?



October 09, 2006
Josh Stern wrote:
> 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?

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.


Sean
« First   ‹ Prev
1 2