About ref used for performance reasons with struct
deadalnix
deadalnix at gmail.com
Sun Feb 10 22:52:28 PST 2013
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.
More information about the Digitalmars-d
mailing list