EqualityComparer.Default 不够聪明

2024-01-14

我正在阅读源代码EqualityComparer<T>.Default却发现它并不是那么聪明。这是一个例子:

enum MyEnum : int { A, B }
EqualityComparer<MyEnum>.Default.Equals(MyEnum.A, MyEnum.B)
//is as fast as 
EqualityComparer<int>.Default.Equals(0, 1)

enum AnotherEnum : long { A = 1L, B = 2L }
//is 8x slower than
EqualityComparer<long>.Default.Equals(1L, 2L)

从 EqualityComparer 中私有方法的源代码中可以明显看出原因。

private static EqualityComparer<T> CreateComparer()
{
    //non-important codes are ignored
    if (c.IsEnum && (Enum.GetUnderlyingType(c) == typeof(int)))
    {
        return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(EnumEqualityComparer<int>), c);
    }
    return new ObjectEqualityComparer<T>();
}

我们可以看到EqualityComparer<int>.Default,EqualityComparer<MyEnum>.Default and EqualityComparer<long>.Default找一个明智的比较者,他的Equals方法如下:

public static bool Equals(int x, int y)
{
    return x == y;  //or return x.Equals(y); here 
                    //I'm not sure, but neither causes boxing
}

public static bool Equals(MyEnum x, MyEnum y)
{
    return x == y;  //it's impossible to use x.Equals(y) here 
                    //because that causes boxing
}

以上两个是clever, but EqualityComparer<AnotherEnum>.Default运气不好,从方法上我们可以看到最后得到了一个ObjectEqualityComparer<T>(), whose Equals方法大概是这样的:

public static bool Equals(AnotherEnum x, AnotherEnum y)
{
    return x.Equals(y);   //too bad, the Equals method is from System.Object
                       //and it's not override, boxing here!
                       //that's why it's so slow
}

我认为这个条件Enum.GetUnderlyingType(c) == typeof(int)毫无意义,如果枚举的基础类型是 int 类型,则该方法可以convertint 与此枚举的默认比较器。但为什么枚举不能基于 long 呢?我想这并不难?有什么特殊原因吗?构建一个类似的比较器x == y对于 enum 来说并不难,对吧?为什么最后它给出了一个缓慢的ObjectEqualityComparer<T>对于枚举(即使它工作正常)?


我认为负责添加此功能的团队根本没有令人信服的理由。所有功能都有实施成本,其中包括(除其他外)记录、编码和测试的时间。

有几个令人信服的原因可以解释为什么这个特定的功能到目前为止还没有被选择而不是其他功能(并且在我看来可能永远不会被淘汰):

  • 它只适用于非常狭窄的场景(比较enums由除int,并在某些内部循环中执行此操作)
  • 如果它给您带来问题,有一个非常简单且可发现的解决方案(编写您自己的比较器)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EqualityComparer.Default 不够聪明 的相关文章

  • LINQ to XML - 如何正确使用 XDocument

    现在我首先要说的是 这确实是一项任务 然而 在我遇到 Linq to XML 语法之前 我几乎已经完成了它 我有 2 个课程 曲目和 CD 现在作为作业的一部分 我创建了一张 CD 然后向其中添加了一些曲目 在搜索了大量完美解释了如何从 x
  • 有没有比这更快的方法来查找目录和所有子目录中的所有文件?

    我正在编写一个程序 需要在目录及其所有子目录中搜索具有特定扩展名的文件 这将在本地驱动器和网络驱动器上使用 因此性能是一个问题 这是我现在使用的递归方法 private void GetFileList string fileSearchP
  • 在 Windows Phone 上启动 pdf 文件时出现 System.Runtime.InteropServices.COMException

    我正在尝试使用我之前在另一个应用程序上使用过的以下工作代码打开 pdf 文件 但这一次 当流程到达此行时 我收到 System Runtime InteropServices COMException Windows System Laun
  • 当我单击 GridView 项时返回 ImageView 实例

    当我点击GridView项时如何返回ImageView实例 我为 ItemClick 创建自定义绑定事件 public class ItemClickSquareBinding MvxBaseAndroidTargetBinding pri
  • 身份未映射异常

    System Security Principal IdentityNotMappedException 无法转换部分或全部身份引用 该错误仅在应用程序注册后出现一次 当 SecurityIdentifier 无法映射时 例如 返回 Ide
  • 使用 VSTO 更改 Outlook 设置

    我刚刚花了大约 4 个小时试图弄清楚如何以编程方式检索 设置 Microsoft Outlook 2010 的 Outlook 设置 我所说的 设置 是指文件 选项 邮件下的设置 我想做的是检索用户设置的设置列表 自动化我们每天需要在某些消
  • 如何避免选择项目时 winforms 树视图图标发生变化

    我正在一个小型 C Winforms 应用程序中尝试树视图 我已经以编程方式将 ImageList 分配给树视图 并且所有节点都很好地显示了它们的图标 but当我单击一个节点时 它的图标会发生变化 变为 ImageList 中的第一个图像
  • C中有const吗?

    这个问题可能很幼稚 但是 有没有constC 中的关键字 从哪个版本开始 之间有任何语义和 或句法差异吗const在 C 和 C 中 C 和 C 之间在语法上没有差异const关键字 除了一个相当晦涩的关键字 在 C 中 自 C99 起 您
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 如何检测斑点并将其裁剪成 png 文件?

    我一直在开发一个网络应用程序 我陷入了一个有问题的问题 我会尝试解释我想要做什么 在这里您看到第一个大图像 其中有绿色形状 我想要做的是将这些形状裁剪成不同的 png 文件 并使它们的背景透明 就像大图像下面的示例裁剪图像一样 第一张图像将
  • 捕获当前正在播放的声音

    是否可以捕获计算机上当前播放的声音 如果能够将其保存为 mp3 就好了 但我认为这样做会存在一些法律问题 所以 wav 也可以 我环顾四周 有人建议使用虚拟音频线之类的东西 在 C 中捕获声音输出 https stackoverflow c
  • CMake - 将预构建库链接到 C# 项目

    我正在使用 CMake 构建 C 库 该库依赖于已构建的库 dll 我似乎无法让图书馆链接到我的图书馆 我尝试过使用target link libraries mylib external lib 我也尝试过暴力破解 reference e
  • 我的 C# .NET 团队是否应该迁移到 Windows Presentation Foundation? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在不使用reinterpret_cast的情况下使用dlsym()加载函数?

    我正在尝试使用 clang tidy 来强制执行 C 核心指南 虽然它确实有很多有效点 但有一件事我无法真正解决 dlsym 返回一个void 我需要以某种方式将其转换为正确的函数指针 为此 我使用reinterpret cast 由于指南
  • 抽象类和接口之间的区别[重复]

    这个问题在这里已经有答案了 可能的重复 接口与基类 https stackoverflow com questions 56867 interface vs base class 我不明白抽象类和接口之间的区别 我什么时候需要使用哪种字体
  • 如何在 C++ 中使用 PI 常数

    我想在一些 C 程序中使用 PI 常数和三角函数 我得到三角函数include
  • 在 MVVM 中,可以在视图后面的代码中访问 ViewModel 吗?

    在 MVVM 模式中 是否可以接受甚至可以访问视图代码后面的 ViewModel 属性 我有一个可观察的集合 它填充在 ViewModel 中 我需要在视图中使用它来绑定到带有链接列表的无限滚动条 IE private LinkedList
  • SSBO 是更大的 UBO?

    我目前正在 OpenGL 4 3 中使用 UBO 进行渲染 以将所有常量数据存储在 GPU 上 诸如材料描述 矩阵等内容 它可以工作 但是 UBO 的小尺寸 我的实现为 64kB 迫使我多次切换缓冲区 减慢渲染速度 我正在寻找类似的方法来存
  • 如何仅更改 DateTime 的日期部分,同时保留时间部分?

    我在代码中使用了很多 DateTime 我想将这些日期时间更改为我的特定日期并保留 时间 1 2012 02 02 06 00 00 gt 2015 12 12 06 00 00 2 2013 02 02 12 00 00 gt 2015
  • 当我读取 500MB FileStream 时出现 OutOfMemoryException

    我使用 Filestream 读取大文件 gt 500 MB 但出现 OutOfMemoryException 任何有关它的解决方案 我的代码是 using var fs3 new FileStream filePath2 FileMode

随机推荐

  • 更新 Dojo 提供

    我在一个项目中使用 Dojo 1 9 但我不明白正确的替代方案dojo provide与传统风格相比 AMD 风格 我正在读书this http dojotoolkit org reference guide 1 9 dojo provid
  • Python 深度嵌套工厂函数

    在 学习Python 中遇到了工厂函数 本教科书示例有效 def maker N def action X return X N return action gt gt gt maker 2
  • 将字符串中的数字范围替换为单个数字

    有没有办法将字符串中的数字范围替换为单个数字 数字的范围可以是 n n 最有可能是 1 15 也可以是 4 10 范围可以用 a 表示 a lt I would like to buy 1 3 cats 或与单词 b 一起使用 例如 to
  • 跨两个数据源的事务管理(ChainedTransactionManager)-SpringBoot

    为什么 Spring ChainedTransactionManager 被弃用 spring 是否提供任何替代库来支持多个事务管理器 我的用例 我们正在构建一个连接到两个数据源 db1 和 db2 的 Spring Boot 应用程序 它
  • 正确停止 Tika 服务器

    为了启动可以从 localhost 以外的主机访问的 Tika 服务器 我们知道要走的路是 假设我有版本 1 7 并且想要在端口 9998 上运行 java jar tika server 1 7 SNAPSHOT jar host 0 0
  • 未捕获的类型错误:$(...).owlCarousel 不是函数

    我已将 owlCarousel 添加到我的页面 但我收到这个错误 并坚持了几个小时 HTML code custom js 中的函数 owl hero owlCarousel navigation true Show next and pr
  • 如何从 Twitter API 和趋势线获取关注者数量

    我正在为 Twitter 编写一些关于随时间推移的关注者数量的报告 但是经过大量搜索和反复试验后 我无法获得随时间推移的关注者数量 特别是过去的关注者数量 我知道有一个 API 可以获取关注者的个人 userId 但这对于我的需要来说有点过
  • Jenkins Subversion 签出失败 - “E175002:CRLF 预计在块末尾:-1/-1”

    我有一个 Jenkins v2 107 2 实例 作为 Windows 服务运行 它正在通过 Subversion 从 Visual SVN 服务器 在单独的 Windows PC 上 检查多个项目 其中一个项目 最大的 2 7GB 偶尔会
  • 如何使用 jquery 在 iframe 中选择标签?

    我试图弄清楚如何选择然后修改 HTMLiframe我生成 iframe 显示各种媒体 图像 pdf 等 为了显示不同的项目 我最初使用如下方式创建它 mydiv html 然后 根据需要 使用如下内容更新其内容 myiframe attr
  • 用于在 HTML 表中查找行索引的 jQuery 语法

    1 如何查找 HTML 表格中的行号 索引 生成的表没有任何行 ID 例如 我生成了一个纯 HTML 表格 其中有 10 行 我正在向该表动态添加行 在现有行之间 由于我要添加新行 现有的行索引将会更改 现在我需要在添加新行之前找到每行的索
  • 如何避免在 Windows 中过度填充 PATH 环境变量?

    我想知道您使用什么方法来管理系统中的可执行文件 例如 我几乎可以通过命令行访问所有内容 但现在我遇到了路径字符串的限制 因此我无法添加更多目录 那么你有什么推荐呢 很久以前 我尝试在属于该路径的目录中使用可执行文件的软链接 但这种方法不起作
  • 是否可以对两个转换字符组合使用格式修饰符?

    我知道如何使用 log4j 输出类名和方法名 这两个字段都可以单独对齐和填充 例如这个模式 d ISO8601 5p 10C 1 10M m n 产生类似的东西 2012 09 20 08 25 12 111 WARN Class meth
  • Windows 无法在本地计算机上启动 Apache CouchDB 服务

    我已在 Windows 计算机上安装了 CouchDB 但在启动 CouchDB 服务时 我收到如下消息 Windows 无法在本地计算机上启动 Apache CouchDB 服务 该服务没有返回错误 这可能是 Windows 内部错误或内
  • 使用bundle运行gitlab服务器:命令未找到错误

    我不知道发生了什么 sudo 服务 gitlab 启动 Starting both the GitLab Unicorn and Sidekiqscript web line 21 bundle command not found 查看我的
  • 如何在 cygwin 上安装 cURL?

    我尝试在 cygwin 上启用curl 但它说bash curl command not found 如何在 cygwin 上安装curl 我刚刚遇到这个 1 从以下位置找到cygwin setup exe文件http cygwin com
  • 使文本高度为 div 的 100%?

    我正在尝试使文本的高度为 100 div但它不起作用 它只是变成了100 body font size 有什么办法让它跟随div高度吗 The div高度是整个页面的 4 当您调整大小 更改分辨率时 我不希望文本跟随它 为了获得我想要的结果
  • 是否可以在打字稿中创建动态 getter/setter?

    我是 TypeScript 新手 我正在尝试将我们的应用程序从 es2016 重写为 TypeScript 我的任务是拥有一个具有数据属性的类 并使数据对象中的每个元素可用作类属性 我被这段 JavaScript 代码困住了 for let
  • Django:关闭http响应消息的控制台输出

    所以我们用 django 制作了一个应用程序 每次收到请求时它都会在控制台上打印所有这些 http 响应消息 Date String GET urlpath blah blah 200 216 Date String DELETE anot
  • jQuery 数据表问题

    当使用jQuery 数据表插件 http datatables net 为什么我会收到此错误 k 未定义 style typeof e saved aaSorting 未定义 我发布这个答案是为了记录一些东西以供自己将来参考 我希望它能对其
  • EqualityComparer.Default 不够聪明

    我正在阅读源代码EqualityComparer