所以,我(我想)理解in参数修饰符的作用.但它的作用似乎是多余的.
通常,我认为使用a的唯一原因ref是修改调用变量,这是明确禁止的in.因此,通过in引用传递在逻辑上等同于传递值.
是否有某种性能优势?我认为,在事物的后端,ref参数必须至少复制变量的物理地址,该地址应与任何典型的对象引用相同.
那么,那么只是在更大的结构中的优势,还是有一些幕后编译器优化使其在其他地方具有吸引力?如果是后者,为什么我不应该把每个参数都做成in?
dym*_*oid 57
in 最近被引入了C#语言.
in实际上是一个ref readonly.一般来说,只有一个用例in可以提供帮助:处理大量readonly structs的高性能应用程序.
假设你有:
readonly struct VeryLarge
{
public readonly long Value1;
public readonly long Value2;
public long Compute() { }
// etc
}
Run Code Online (Sandbox Code Playgroud)
和
void Process(in VeryLarge value) { }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,VeryLarge当在Process方法中使用此结构时(例如,在调用时value.Compute()),结构将通过引用传递而不创建防御性副本,并且编译器确保结构不变性.
请注意,struct使用in修饰符传递not-readonly 将导致编译器在调用struct的方法并访问上述方法中的属性时创建防御性副本Process,这将对性能产生负面影响!
有一个非常好的MSDN博客文章,我建议仔细阅读.
如果您想获得更多历史背景 - 介绍in,您可以在C#语言的GitHub存储库中阅读此讨论.
一般来说,大多数开发人员都认为引入in可能被视为一个错误.这是一种相当奇特的语言特征,只能用于高性能边缘情况.
Eri*_*ert 23
通过
in引用传递似乎在逻辑上等同于传递值.
正确.
是否有某种性能优势?
是.
我认为,在事物的后端,
ref参数必须至少复制变量的物理地址,该地址应与任何典型的对象引用相同.
不要求对对象的引用和对变量的引用都具有相同的大小,并且不要求任何一个是机器字的大小,但是是的,实际上两者都是32位32位机和64位机器上的64位.
你认为"物理地址"与它有什么关系我不清楚.在Windows上,我们使用虚拟地址,而不是用户模式代码中的物理地址.在什么情况下你会想象一个物理地址在C#程序中是有意义的,我很想知道.
也不要求将任何类型的引用实现为存储的虚拟地址.在CLI规范的一致实现中,引用可以是GC表中的不透明句柄.
只是在更大的结构中的优势?
降低传递较大结构的成本是该功能的激励方案.
请注意,无法保证in任何程序实际上更快,并且它可以使程序更慢. 所有关于表现的问题必须通过实证研究来回答.很少有优化总是胜利 ; 这不是"永远胜利"的优化.
是否有一些幕后编译器优化使其在其他地方具有吸引力?
如果这样做不违反C#规范的规则,则允许编译器和运行时进行任何优化.据我所知,还没有针对in参数的这种优化,但这并不排除将来的这种优化.
为什么我不应该把每个参数都放进去?
好吧,假设您创建了一个int参数而不是in int参数.是什么成本?
假设它是a double并且你将它改为in double.同样,现在变量无法注册到高性能浮点寄存器中.这不仅具有性能影响,还可以改变程序行为!允许C#以高于64位的精度执行浮点运算,并且通常只有在可以注册浮点数时才这样做.
这不是免费优化.您必须根据替代方案衡量其绩效.你最好的选择就是不要像设计指南所说的那样首先制作大型结构.
小智 6
有.传递a时struct,in关键字允许进行优化,编译器只需要传递指针,而不存在方法更改内容的风险.最后一个是关键 - 它避免了复制操作.在大型结构上,这可以创造一个与众不同的世界.
| 归档时间: |
|
| 查看次数: |
5815 次 |
| 最近记录: |