为什么不尽可能在方法参数中使用“ in”?

时间:2019-02-01 04:17:42

标签: c#

在C#中,我们可以在struct方法参数上指定in,以便将它们作为只读引用传递:

public int TimesTwo(in int number)
{
    return number * 2;
}

这与使用ref几乎相同,但是不允许修改参数:

public int TimesTwo(in int number)
{
    number *= 2; // Compiler error
    return number;
}

此外,它不需要在调用时指定关键字,就像ref那样:

var x = 1;
var y = TimesTwo(x);
var z = TimesTwo(in x);
// y and z are both 2

在某些情况下,这是不可能的,例如当您需要修改参数或使用不允许in的异步或迭代器方法时。但是问题是,在仅读取参数的99%的情况下,为什么不指定in

指定in时,将传递的参数复制到局部变量。这种复制可能会花费一些时间,对于紧密循环中的大型结构,例如Microsoft says here,这会很明显。

使用in,将传递引用,因此不会进行复制。也许在大多数情况下不复制所节省的时间可以忽略不计,但是我想知道除了标准“它使代码混乱”或“这是您不应该担心的微观优化”之外是否还有其他原因。 >

据我所知,绕过结构复制的这种“微优化”正是引入in的原因。还有其他原因为什么把它丢到性能关键代码的任何地方都是不好的做法?

1 个答案:

答案 0 :(得分:5)

它也适合于紧密耦合。例如,以下来自MSDN(https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier)的方法:

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // ok
Method(5L); // CS1503: no implicit conversion from long to int

这是一个有趣的优化链接(我复制了他们的结果) 其中讨论了readonly structreadonly refinhttps://faithlife.codes/blog/2017/12/in-will-make-your-code-slower/

Method                  Mean
PointByValue            25.09 ns
PointByRef              21.77 ns
PointByIn               34.59 ns  // our guy
ReadOnlyPointByValue    25.29 ns
ReadOnlyPointByRef      21.78 ns
ReadOnlyPointByIn       21.79 ns

进一步阅读(来源:乔恩·斯基特):

微优化:只读字段的惊奇不足

https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/