我正在查看 Dictionary<TKey, TValue>
.NET Core 中的代码,我注意到一种编码模式也用于一些内置数据结构,如 Queue<T>
或 Stack<T>
和 List<T>
.
我们有:
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/