Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to use the "in" modifier with a readonly struct?

Tags:

c#

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?

like image 643
MineR Avatar asked May 18 '18 03:05

MineR


People also ask

What is readonly struct?

The readonly keyword is a C# modifier used to limit access to all the data members of a struct. If the readonly modifier is used in the declaration of a struct, then: The members of the struct are read-only. None of the members can have setters. A parameterized constructor is used to initialize the data members.

What is the best way to declare a method parameter that behaves as a readonly reference variable?

Declaring in parameters in parameters are declared by using in keyword as a modifier in the parameter signature. For all purposes the in parameter is treated as a readonly variable. Most of the restrictions on the use of in parameters inside the method are the same as with readonly fields.

Can struct have reference types?

Yes they can. It depends. Many hold the stance that a struct should be immutable, and in this case, holding a reference to an object could mean it isn't. But it depends on the situation.

Can we inherit structure in C#?

A structure type can't inherit from other class or structure type and it can't be the base of a class. However, a structure type can implement interfaces.


1 Answers

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).

like image 129
Michael Liu Avatar answered Nov 03 '22 02:11

Michael Liu