About ref used for performance reasons with struct
deadalnix
deadalnix at gmail.com
Sun Feb 10 23:01:13 PST 2013
On Monday, 11 February 2013 at 06:52:33 UTC, deadalnix wrote:
> Ok, We have 2 usages of ref : when you actually need to modify
> informations, and for performance reasons. Let's talk about the
> second one.
>
> Passing by ref to improve performance is not ideal. First this
> is quite hard to know when it is actually faster to pass by ref
> and to pass by value, especially in generic code. Secondly it
> is easy to forget to use ref at some location, and a lot of
> small performance improvement are lost in the process. Finally,
> this may be error prone.
>
> I'm thinking about it for a while now and I'm now convinced
> that we should allow the compiler to do that job for us. Let me
> explain.
>
> When a function accept a struct, the compiler is free to use
> that function, or an altered one taking a reference as
> parameter. Here are some rules the compiler can use to know
> which one to call from callee side :
>
> The caller is free to call the ref version of the function
> unless (rules evaluate in order) :
> - The argument is an rvalue (in such case, no postblit is
> executed as well).
> - The argument is shared.
> - The argument's postblit in not pure (weakly).
>
> The callee isn't modified for the vanilla function, but must
> create a local copy of the argument in the following reasons in
> the ref version :
> - The argument is binded to a mutable ref.(even as hidden
> argument as for member method).
> - The argument is actually modified.
> - address of anything coming from the struct is taken.
>
> The compiler is free to apply such treatment only in a branch
> of the callee, ie :
>
> // Compiler choose to create an alternative ref version for
> performance.
> void foo(MyStruct s) {
> if(condition) {
> // Operation require a copy to not alter what the
> caller see.
> // A s is copied on stack and postblit is called.
> s.field = 5;
> } else {
> // No operation requiring local copy is performed.
> // No local copy is created.
> }
> }
>
> The compiler is however disallowed to create multiple copies in
> the callee. If several branches requires it, then the copy have
> to be made in a common branch.
>
> Note that the compiler don't HAVE to do this, but is allowed
> to. Modifying the spec in such way allow the compiler to avoid
> many copies of struct let us get rid of most ref parameters,
> keeping them for what they really are for.
EDIT: I forgot one condition for the callee, it is disallowed to
copy the struct or any part of it that contain reference/pointer
is the postblit isn't strongly pure.
More information about the Digitalmars-d
mailing list