c# - 数字比较作为 uint 是否比 c# 中的普通 int 快

标签 c# .net .net-core clr

我正在研究一些 .Net 核心库是如何实现的,引起我注意的许多事情之一是在 Dictionary<TKey, TValue> 中。对一些数字比较进行分类,其中完成了对 (uint) 的转换即使在我幼稚的眼中,这并没有影响逻辑。
例如在

do { // some magic } while (collisionCount <= (uint)entries.Length);
collisionCount初始化于 0并且总是递增( collisionCount++ ),因此 entries作为一个数组,其长度也不会为负 see source code
if ((uint)i >= (uint)entries.Length) { // some code }
source code line
哪里i执行以下操作时,在某些情况下可能会变成负数,see debug img
i = entry.next; 
因此将其用作正数会改变程序流程(由于二进制补码)
查看类代码的摘录:
// Some code and black magic

uint hashCode = (uint)key.GetHashCode();
int i = GetBucket(hashCode);
Entry[]? entries = _entries;
uint collisionCount = 0;
if (typeof(TKey).IsValueType)
{
    i--;
    do
    {
        if ((uint)i >= (uint)entries.Length) // <--- Workflow impact
        {
            goto ReturnNotFound;
        }

        entry = ref entries[i];
        if (entry.hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entry.key, key))
        {
            goto ReturnFound;
        }

        i = entry.next;

        collisionCount++;
    } while (collisionCount <= (uint)entries.Length);
}

// More cool stuffs
是否有任何性能提升或这是什么原因?

最佳答案

链接的字典源包含此注释;
//应该是一个while循环 https://github.com/dotnet/runtime/issues/9422
//测试是否要删除范围检查以进行以下数组访问
if ((uint)i >= (uint)entries.Length)
{
转到 ReturnNotFound;
}

条目 = 引用条目 [i];
uint这里的比较不是更快,但它有助于加快数组访问。链接的 github 问题讨论了运行时编译器的限制,以及此循环结构如何允许进一步优化。自此 uint已经显式进行了比较,编译器可以证明0 <= i < entries.Length .这允许编译器忽略数组边界测试并抛出 IndexOutOfRangeException否则将需要这样做。
换句话说,在编写此代码时,执行了性能分析。编译器不够聪明,无法编写更简单、更易读的代码,并尽可能快地运行。因此,对编译器局限性有深刻理解的人调整了代码以使其更好。

关于c# - 数字比较作为 uint 是否比 c# 中的普通 int 快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62545795/

相关文章:

c# - 将 ToolStripSplitButton.DropDown 按钮宽度设置为 0

.net-core - 为什么Curve25519即使参数错误也能正确计算 key 对?

c# - 如何在 azure applicationInsights 中创建自定义列

c# - 通过 IoC 影响带有属性的 AOP;代码味还是优雅?

c# - 数组哪些页面到磁盘

c# - 如何区分编译器生成的类和 .NET 中的用户类

node.js - 并行或同时构建 dotnet 核心

c# - 如何确定是否正在使用 Microsoft.VisualStudio.Web.CodeGeneration.Design?

c# - 需要帮助从 C# 中的 HTML 页面中提取标签

c# - 为什么发送电子邮件需要这么长时间?