我正在查看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;
Run Code Online (Sandbox Code Playgroud)
我不太确定为什么我们要保留比较器的引用和条目的变量,对我来说,它仍然引用相同的字段。
如果使用相同的方法主体,这并不像在某个时候重新分配了该字段。
如果没有重新分配引用,并且编译器进行了一些优化来避免this.field遍历,那么复制引用又有什么用呢?
看起来它可能是手动优化,无论是为了速度,还是为了更小的代码大小,或两者兼而有之。
就时钟周期而言,取消引用局部变量比取消引用成员变量更便宜(这意味着 C# 编译器和 JITter 并不像我希望的那样智能),而且在 IL 方面也更紧凑代码长度。
局部变量通常可以用一条 IL 指令来访问,并且在 JITting 后通常也可以只用一条机器代码指令来访问。
成员变量需要更多工作。在IL级别,我们必须指定我们想要访问this指针,并且我们想要访问距它有偏移量的东西,并且我们必须指定标识成员变量的字段。JITting之后,就看JITter的智能程度了,如果JITter能保证某个寄存器总是包含 的地址,理论上一条指令就可以完成this,但是这样的保证很难有,所以可能会发生什么是需要一条指令加载this到寄存器中,并需要另外一条指令来访问距该寄存器偏移量的字段。
在编写应用程序代码时,这样的编码是不值得的。但是,当编写一个供全球大量人员全天候使用的库时,编写代码以便到处压缩时钟周期是有意义的。
| 归档时间: |
|
| 查看次数: |
53 次 |
| 最近记录: |