c# - 在永远不会重新分配字段的情况下,复制方法主体中字段的引用以读取它有什么好处?

标签 c# .net .net-core

我正在查看 Dictionary<TKey, TValue> .NET Core 中的代码,我注意到一种编码模式也用于一些内置数据结构,如 Queue<T>Stack<T>List<T> .

例如关于: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Collections/Generic/Dictionary.cs#L482

我们有:

Entry[] entries = _entries;
IEqualityComparer<TKey> comparer = _comparer;

我不太确定为什么我们保留比较器和条目引用的变量,对我来说它仍然引用相同的字段。

如果相同的方法体,字段不会在某个时候被重新分配。

如果编译器做了一些优化可以避免 this.field,如果不重新分配引用,那么复制引用有什么意义呢?遍历?

最佳答案

看起来它可能是手动优化,要么是为了速度,要么是为了更小的代码大小,或者两者兼而有之。

就时钟周期而言,取消引用局部变量比取消引用成员变量更便宜,(这意味着 C# 编译器和 JITter 并不像我希望的那样聪明,)而且它在IL 代码长度方面。

一个局部变量通常可以用一条 IL 指令访问,在 JIT 之后通常也可以只用一条机器码指令访问。

成员变量需要更多的工作。在 IL 级别,我们必须指定我们想要访问 this 指针,并且我们想要访问距它有偏移量的内容,并且我们必须指定标识成员变量的字段。 JITting之后,就看JITter有多聪明了,理论上如果JITter能保证某个寄存器总是包含this的地址的话,一条指令就可以搞定,但是这样的保证很难做到有,所以可能发生的情况是,它需要一条指令将 this 加载到一个寄存器中,并且需要一条指令来访问该寄存器偏移量处的字段。

在编写应用程序代码时,永远不值得这样编码。但是,当编写一个供全局大量人员全天候使用的库时,编写代码以在各处压缩时钟周期是有意义的。

关于c# - 在永远不会重新分配字段的情况下,复制方法主体中字段的引用以读取它有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53952324/

相关文章:

c# - UpdatePanel 中的 AddThis 控件 - 确保它们在异步回发后正确呈现

c# - 从 ListItem 的 SharePoint API 获取预览/灯箱 URL

c# - 获取子进程的形式

c# - 在 UWP App 和 .NET Core 之间共享库

entity-framework - 从 dotnet 核心使用的硬编码 EF6 连接字符串名称

c# - WPF 绑定(bind)到父窗口中的元素

c# - 从 C# 中读取 XML

c# - 关于 .NET 中垃圾收集器的问题(内存泄漏)

c# - EventArgs 类和 event 关键字之间是否存在特殊关联?

c# - ASP.NET Core DI 构造函数与 RequestServices