【问题标题】:Why is ToUpperInvariant() faster than ToLowerInvariant()?为什么 ToUpperInvariant() 比 ToLowerInvariant() 快?
【发布时间】:2013-09-10 13:23:22
【问题描述】:

我在 CLR 中通过 Jeffrey Richter 的 C# 读到 String.ToUpperInvariant()String.ToLowerInvariant() 快​​。他说这是因为 FCL 使用 ToUpperInvariant 来规范化字符串,所以该方法是超优化的。在我的机器上运行几个快速测试,我同意ToUpperInvariant() 确实稍微快一些。

我的问题是,是否有人知道该功能实际上是如何在技术层面上优化的,和/或为什么同样的优化也没有应用于 ToLowerInvariant()


关于“重复”:提议的“重复”问题确实无法回答我的问题。我了解使用ToUpperInvariant 而不是ToLowerInvariant 的好处,但我想知道ToUpperInvariant 如何/为什么表现更好。 “重复”中没有提到这一点。

【问题讨论】:

  • 看起来适合您友好的 ildasm 或最喜欢的反编译器。
  • ToUpperInvariant()ToLowerInvariant() 最终都调用了InternalChangeCaseString(),所以魔术一定是在该方法内(或在由该方法调用的方法中)进行了一些优化。
  • @MatthewWatson, Romuku - 在使用 ReSharper 反编译器查看 InternalChangeCaseString 时有效,这很有趣,因为我怀疑这两种方法最终可能会调用一些共享函数。然而,由于 InternalChangeCaseString 是直接在 CLR 中实现的,我想确切知道他们实施了哪些优化会导致这种行为的希望不大。
  • 也许这也很有趣:stackoverflow.com/questions/297703/…

标签: c# string optimization clr normalization


【解决方案1】:

由于现在read the CLR source which implements InternalChangeCaseString 更容易,我们可以看到它主要调用Win32 函数LCMapStringEx。对于dwMapFlags 参数,似乎没有关于传递LCMAP_UPPERCASELCMAP_LOWERCASE 的性能的注释或任何讨论。调用InternalChangeCaseString 使用标志isToUpper,如果true 可能会导致编译器(或JITter)更好地优化,但是由于对LCMapStringEx 的调用必须设置ap/invoke 调用框架并且调用本身具有做工作,我不确定在那里节省了很多时间。

也许该建议是对其他一些实现的保留,但我看不出任何可以以某种方式提供显着速度优势的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-02
    • 2015-07-24
    • 1970-01-01
    • 2019-04-18
    • 2014-07-06
    相关资源
    最近更新 更多