Reputation: 2204
In C# 7.2, are readonly structs always passed to functions as if the "in" parameter is present? If not, in what case would it be useful to copy the memory given that it's readonly?
I have a readonly struct:
public readonly struct Vec2
{
public readonly double X;
public readonly double Y;
}
So would there be a performance difference between these two methods when called billions of times:
public double Magnitude1(Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
public double Magnitude2(in Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
And if so, why doesn't the compiler recognize that Vec2 is a readonly struct and just pass it as if "in" were present? Is there an instance where you might want to pass a readonly struct without the "in" modifier?
Upvotes: 10
Views: 746
Reputation: 55469
Are readonly structs always passed to functions as if the "in" parameter is present?
No. Without the in
modifier, readonly
structs are passed by value, not by reference.
If not, in what case would it be useful to copy the memory given that it's readonly?
It would be useful to copy the memory if you wanted to guarantee the memory didn't change. Keep in mind that a struct can be changed even if it's readonly
. For example:
readonly struct S
{
public readonly int I;
public S(int i) { this.I = i; }
}
class Program
{
static S s1 = new S(1);
static void Main()
{
A(s1);
}
static void A(in S s2)
{
Console.Write(s2.I);
s1 = new S(2); // This is legal even though S is readonly!
Console.Write(s2.I);
}
}
With the in
modifier on parameter s2
, the output is 12. Without the in
modifier, the output is 11.
This difference in behavior means the compiler cannot transparently add in
modifiers to readonly struct
parameters. (Even if method A
didn't modify s1
, another thread could.)
So would there be a performance difference between these two methods when called billions of times?
There might be; measure it and see. I'd expect that the larger the struct, the slower it would be to pass by value.
And if so, why doesn't the compiler recognize that Vec2 is a readonly struct and just pass it as if "in" were present? Is there an instance where you might want to pass a readonly struct without the "in" modifier?
Maybe if the struct
were very small (say, 8 bytes or less), passing by value (e.g., in a CPU register) could be cheaper than passing by reference (and then having to dereference the pointer).
Upvotes: 11