上与下案例

Par*_*ppa 79 language-agnostic string uppercase

在进行不区分大小写的比较时,将字符串转换为大写或小写更有效吗?它甚至重要吗?

在这篇SO帖子中建议C#使用ToUpper更有效,因为"Microsoft以这种方式优化了它".但我也读过这个论点,转换ToLower与ToUpper取决于你的字符串包含的内容,并且通常字符串包含更多小写字符,这使得ToLower更有效.

特别是,我想知道:

  • 有没有办法优化ToUpper或ToLower,使一个比另一个更快?
  • 在大写或小写字符串之间进行不区分大小写的比较是否更快?为什么?
  • 是否存在任何编程环境(例如C,C#,Python等),其中一个案例明显优于另一个案例,为什么?

Jon*_*eet 88

由于某些文化,特别是土耳其的"有趣"特征,转换为大写或小写以进行不区分大小写的比较是不正确的.而是使用具有适当选项的StringComparer.

MSDN 对字符串处理有一些很好的指导.您可能还想检查您的代码是否通过了土耳其测试.

编辑:注意Neil关于序数不区分大小写的比较的评论.整个领域非常模糊:(

  • 是StringComparer很棒,但问题没有得到解答......在你不能使用StringComparer的情况下,例如对字符串的swtich语句; 我应该在开关中使用ToUpper还是ToLower? (14认同)
  • 使用StringComparer和"if"/"else"而不是使用ToUpper或ToLower. (6认同)
  • 约翰,我知道转换为小写是不正确的,但我没有听说转换为大写是不正确的.你能提供一个例子或参考吗?您链接的MSDN文章说:"使用OrdinalIgnoreCase进行的比较在行为上是两个调用的组合:在两个字符串参数上调用ToUpperInvariant,并进行Ordinal比较." 在标题为"序数字符串操作"的部分中,它在代码中重申了这一点. (5认同)
  • @Triynko:我认为将*主要*集中在正确性上非常重要,重点是快速得到错误答案通常不会比慢慢得到错误答案更好(有时更糟). (4认同)
  • @Neil:有意思,我没有看到那一点.对于*序数*不区分大小写的比较,我认为这是公平的.毕竟,它必须选择*东西*.对于文化敏感的不区分大小写的比较,我认为仍然存在一些奇怪的行为空间.会在答案中指出你的评论...... (2认同)
  • 虽然这个答案给了作者一个解决方案,但它也回避了这个问题。作者正在寻求信息以在 ToUpper 和 ToLower 之间做出明智的选择以考虑性能问题。虽然提供替代的第三个选择 (StringComparer) 是合法的,但它至少应该在其相对于其他两个选择的性能(不仅仅是其正确性)的上下文中进行框架化。这个答案中没有提到性能。如果它包含诸如“StringComparer.Compare 明显更快(并且更正确),即使只比较 ASCII 文本”之类的内容会更好。 (2认同)
  • @Константин Ван:土耳其语“i”问题 - 请参阅http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html(例如,几十年前我有在土耳其时,由于 Java 中的“mail”.toUpperCase()` 不是“MAIL”而失败的代码。 (2认同)

Ian*_*oyd 22

来自MSDN上的Microsoft:

在.NET Framework中使用字符串的最佳实践

字符串使用的建议

为什么?来自微软:

将字符串规范化为大写

有一小组字符在转换为小写时无法进行往返.

这样一个不能往返的角色的例子是什么?

  • 开始:希腊Rho符号(U + 03f1)ρ
  • 大写: Capital Greek Rho(U + 03a1)Ρ
  • 小写:小希腊语Rho(U + 03c1)ρ

ρ, Ρ, ρ

这就是为什么,如果您想要进行不区分大小写的比较,则将字符串转换为大写,而不是小写.

  • 回到原始问题的答案:对于一个大写变体,有一些语言知道一个以上的小写变体.除非你知道何时使用哪种表示的规则(希腊文中的另一个例子:小西格玛字母,你在单词开头或中间使用σ,在结尾处使用σ(见http://en.wikipedia.org/wiki)/Sigma),您无法安全地转换回小写变体. (3认同)
  • ϱ != ρ,但如果使用大写,那么它本质上不会同时更改为 Ρ,然后比较 Ρ == Ρ 这将是正确的,即使 ϱ != ρ ? (2认同)

Rob*_*ker 19

根据MSDN,传递字符串并告诉比较忽略大小写更有效:

String.Compare(strA,strB,StringComparison.OrdinalIgnoreCase)相当于(但比其更快)调用

String.Compare(ToUpperInvariant(strA),ToUpperInvariant(strB),StringComparison.Ordinal).

这些比较仍然非常快.

当然,如果你一遍又一遍地比较一个字符串,那么这可能不成立.


war*_*ren 12

基于倾向于具有更多小写条目的字符串,ToLower理论上应该更快(许多比较,但很少分配).

在C中,或者当使用每个字符串中可单独访问的元素(例如C字符串或C++中的STL字符串类型)时,它实际上是一个字节比较 - 所以比较UPPER没有什么不同lower.

如果您偷偷摸摸并将字符串加载到long数组中,您将对整个字符串进行非常快速的比较,因为它可以一次比较4个字节.但是,加载时间可能会让它变得不值得.

为什么你需要知道哪个更快?除非你正在进行公制的比较,否则运行几个周期的速度与整体执行的速度无关,听起来像是过早的优化:)

  • 要回答这个问题,为什么我需要知道哪个更快:我不需要知道,我只是想知道.:)这只是一个看到有人提出索赔的案例(例如"比较大写字母串更快!")并想知道它是否真的是真的和/或他们为何提出这种说法. (11认同)

Dan*_*ert 6

微软已经优化ToUpperInvariant(),而不是ToUpper().不同之处在于,不变性更具文化友好性.如果您需要对文化中可能不同的字符串进行不区分大小写的比较,请使用Invariant,否则不变的转换性能应该无关紧要.

我不能说ToUpper()或ToLower()是否更快.我从来没有尝试过,因为我从未遇到过性能问题那么重要的情况.

  • @Medo我不记得优化的确切原因,但由于所有字母都存储为二进制数字,所以2对3位数几乎肯定不是原因,因此十进制数字根据它们的存储方式确实没有意义. (3认同)