Properties: a.b.c = 3

Chad J chadjoan at __spam.is.bad__gmail.com
Wed Jul 29 12:13:34 PDT 2009


Chad J wrote:
> Steven Schveighoffer wrote:
>> Wouldn't the compiler write:
>>
>> //widget.rect.w = 200 translates to
>> auto tmp1 = widget.rect;
>> tmp1.w = 200;
>> widget.rect = tmp1;
>>
>> //widget.rect.h = 100 translates to
>> auto tmp2 = widget.rect;
>> tmp2.h = 100;
>> widget.rect = tmp2;
>>
>> ???
>>
>> Unless you want some serious optimization requirements...
>>
>> -Steve
> 
> It would.
> 
> The optimization you speak of is reference caching.  I often do it by
> hand in deeply nested loops where it actually means a damn.  It's also
> an optimization I think compilers should do, because it is useful in
> many more cases than just this.
> 

I should probably explain this more.

Suppose you have some data structure in memory.

struct Foo
{
	Bar* a;
}

struct Bar
{
	float[] thingies;
}

Then you have a Foo and you need to stroke it's Bar's thingies.

Foo f;
// ...
for ( int i = 0; i < f.a.thingies.length; i++ )
	stroke(f.a.thingies[i]);

Bad bad bad!
For every thingie stroked there is going to be two whole dereferences.
That's if the compiler was smart enough to move "f.a.thingies.length"
outside of the loop.  Otherwise it's more like 3 derefences.  Unlike
mere assignments, those can be expensive, especially if you have a cache
miss.  3 of those.  Ouch.

So rewrite the code like this:

Foo f;
// ...
var things = f.a.thingies; // The reference is now cached.
var len = things.length;
for ( int i = 0; i < len; i++ )
	stroke(things[i]);

Ah, much better.  Only does 1 dereference per thing ever.




More information about the Digitalmars-d mailing list