About ref used for performance reasons with struct

Dan dbdavidson at yahoo.com
Mon Feb 11 14:40:42 PST 2013


On Monday, 11 February 2013 at 16:56:38 UTC, deadalnix wrote:
> On Monday, 11 February 2013 at 16:51:22 UTC, Steven 
> Schveighoffer wrote:
>> On Mon, 11 Feb 2013 10:08:52 -0500, deadalnix 
>> <deadalnix at gmail.com> wrote:
>>
>>> A good rule of thumb to know when to pass by ref for perf is :
>>> - The struct is big, or contains mixed entities (floats and 
>>> ints). 2*size_t seems like a good heuristic from my 
>>> experience.
>>
>> Array slices are 2*sizeof(size_t).  I would expect them to be 
>> always copied and not ref'd.
>>
>
> First, they alway appears to be copied from the dev 
> perspective. That why I put bunch of restrictions in the 
> proposal.
>
> Second, slice are 2*size_t and are not mixed entities (from CPU 
> perspective, pointer are integers). So I don't have numbers, 
> but I expect slice to be faster when passed by copy than when 
> passed by ref.

The idea of compiler choosing the optimal between: 'T t' and 'ref 
const(T) t' has been brought up a few times. Here is one attempt 
at getting numbers to see where a cutoff might be.

http://forum.dlang.org/thread/opufykfxwkkjchqcwgrg@forum.dlang.org

Based on this, and to avoid the boilerplate of read accessors, I 
use the following heuristic. If others have more friendly ways 
I'd be interested.

Thanks
Dan


/** Discriminates a pass type by its size
  */
template PrefersPassByRef(T) {
   static if(isAssociativeArray!T || isDynamicArray!T) {
     enum PrefersPassByRef = false;
   } else static if(T.sizeof > 16 || hasAliasing!T)  {
     enum PrefersPassByRef = true;
   } else {
     enum PrefersPassByRef = false;
   }
}

/** Discriminates a pass type by its size
  */
template PreferredPassType(T) {
   static if(PrefersPassByRef!T) {
     enum PreferredPassType = `const ref `~T.stringof;
   } else {
     enum PreferredPassType = T.stringof;
   }
}

/** Provides mixin for making a field read only.
  *  For example mixin(ReadOnly!_fieldName) provides a getter 
named fieldName.
  */
template ReadOnly(alias name) {
   enum v = name.stringof;
   enum p = name.stringof[1..$];
   enum prefersReference = PrefersPassByRef!(typeof(name));
   static if(prefersReference) {
     mixin(`
public @property auto ref `~p~`() const {
   return `~v~`;
}
`);
   } else {
     mixin(`
public @property auto `~p~`() const {
   return `~v~`;
}
`);
   }
}



More information about the Digitalmars-d mailing list