在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
的原因。还有其他原因为什么把它丢到性能关键代码的任何地方都是不好的做法?
答案 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 struct
,readonly ref
和in
:
https://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
进一步阅读(来源:乔恩·斯基特):
微优化:只读字段的惊奇不足