I'm trying to understand the difference between const ref
and in
, specially when it comes to performance.
I know that in
is equivalent to const scope
, but what does the scope storage class means that references in the parameter cannot be escaped (e.g. assigned to a global variable).
mean? example code is welcome.
How do I decide between const ref
and in
when implementing a function? I know with ref
the object doesn't get copied because it's a reference, but is the same true with in
?
1) the scope
parameter storage class means that you're not allowed to escape a reference to the parameter. Example:
Object glob;
struct S
{
Object o;
void foo(scope Object o)
{
this.o = o; // Not allowed! 'o' must not be escaped
glob = o; // ditto
}
}
Note that DMD is not very good at detecting this. The above example currently compiles, but is not allowed.
scope
is most useful for delegate parameters:
void foo(scope void delegate() dg)
{
/* use dg */
}
void main()
{
int i;
foo({ ++i; });
}
In the above example, no closure needs to be allocated for the anonymous function even though it has an upvalue, because foo
"guarantees" (it is the compiler's job...) that the delegate isn't escaped. DMD currently does implement this optimization.
2) I think the idea is that when both const
and scope
is used, the compiler could theoretically pass by reference or value at will, which is why the in
shortcut is useful. DMD doesn't take advantage of this right now, but it's a handy shortcut nevertheless, and it has some documentation value.
In short, in
won't currently gain you any performance unless it's used on a delegate. ref
can gain you some performance with large structs or static arrays. When ref
is used for performance reasons, const
is often used to document (and enforce) that the ref
is not used to update the original value.