c# - 是否有必要将 "in"修饰符与只读结构一起使用?

标签 c#

在 C# 7.2 中,只读结构是否总是像存在“in”参数一样传递给函数?如果不是,在什么情况下复制内存是有用的,因为它是只读的?

我有一个只读结构:

public readonly struct Vec2 
{
     public readonly double X;
     public readonly double Y;
}

那么当调用数十亿次时,这两种方法之间会有性能差异吗:

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);
}

如果是这样,为什么编译器不能识别 Vec2 是一个只读结构,而只是像“in”存在一样传递它?是否存在您可能想要传递不带“in”修饰符的只读结构的实例?

最佳答案

Are readonly structs always passed to functions as if the "in" parameter is present?

没有。如果没有 in 修饰符,readonly 结构将按值传递,而不是按引用传递。

If not, in what case would it be useful to copy the memory given that it's readonly?

如果你想保证内存没有改变,复制内存会很有用。请记住,即使结构是 readonly 也可以更改。例如:

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);
    }
}

在参数 s2 上使用 in 修饰符,输出为 12。没有 in 修饰符,输出为 11。

这种行为差异意味着编译器无法透明地将 in 修饰符添加到 readonly struct 参数。 (即使方法 A 没有修改 s1,另一个线程也可以。)

So would there be a performance difference between these two methods when called billions of times?

可能有;量一下看看。我预计结构越大,按值传递的速度就越慢。

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?

也许如果 struct 非常小(例如,8 个字节或更少),按值传递(例如,在 CPU 寄存器中)可能比按引用传递(然后必须取消引用)更便宜指针)。

关于c# - 是否有必要将 "in"修饰符与只读结构一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50403347/

相关文章:

c# - 为什么我的 Linq 语句被执行了两次?

c# - Microsoft Visual C++ 2010 SP1 可在 Azure 上重新分发吗?

c# - 将十六进制代码发送到串口

c# - 检查 Key 是否存在于 NameValueCollection 中

c# - 如何在 silverlight 中将一个可观察集合与另一个可观察集合进行排序?

c# - 在服务器应用程序中存储配置信息的最佳方法是什么? (无数据库)

c# - 当我回发到 Controller 时,模型的所有值均为空

c# - 反序列化接口(interface)实例的集合?

c# - 从字符串 ascii 转换为字符串 Hex

c# - 在任务计划程序 2.0 中获取错误代码 -2147216615