是否有充分的理由对字符串使用文化敏感的比较器?

Posted

技术标签:

【中文标题】是否有充分的理由对字符串使用文化敏感的比较器?【英文标题】:Is there a good reason to use a culture-sensitive comparer for strings? 【发布时间】:2015-03-28 00:04:14 【问题描述】:

翻遍.NET代码后发现Comparer<string>.Default生成的比较器和string.CompareTo的实现都使用了文化敏感的字符串比较(具体来说是对CultureInfo.CurrentCulture敏感)。有序集和映射的默认行为是使用此比较器。

但是,F# 的有序 SetMap 为使用 String.CompareOrdinal 的字符串创建了一个特殊的比较器。因此,使用字符串键时,这些集合比最近的System.Collections.Immutable 排序字典和排序映射要快得多,如下图所示:

Chart

我也在开发一个不可变集合库(在图表中称为 Funq)。在执行此优化之前,我遇到了与那些集合相同的性能问题。

考虑到我肯定想在有序集合中保持预期的顺序,这种优化会导致任何问题吗?您能否举出在特定文化中表现不符合预期的具体示例?

【问题讨论】:

【参考方案1】:

当然:

"a""B" 的排序方式不同,使用 CompareOrdinal 与使用 CurrentCulture、InvariantCulture 和 InvariantCulture 忽略大小写。

演示:http://rextester.com/QSCF42204

string a = "a";
string b = "B";
Console.WriteLine(Comparer<string>.Default.Compare(a, b));
Console.WriteLine(string.CompareOrdinal(a, b));
Console.WriteLine(string.Compare(a, b, true, System.Globalization.CultureInfo.InvariantCulture));
Console.WriteLine(string.Compare(a, b, false, System.Globalization.CultureInfo.InvariantCulture));

【讨论】:

哦,没想到这么简单!为什么"a" &lt; "B"InvariantCulture 中?或者更确切地说,是谁决定的"a" &lt; "A" @JustGreg:因为在字典中"azalea" 排在"Bali" 之前(选择任何西方语言,选择任何字典)。或者百科全书。 @JustGreg:您为什么认为"a" &lt; "B""a" &lt; "A" 相关?为什么你认为"a" &lt; "A"(在其中一些,它不是) 抱歉,不知为何我是个白痴。可能是睡眠太少了。我跑了rextester.com/DHJK8080,发现"A" &gt; "a"(区分大小写)。我想这有点道理。这并不重要。你熟悉其他文化的例子吗?另外,您认为“预期”的顺序是什么?作为程序员,序号比较更有意义,我个人希望a 出现在B 之后。 作为一名程序员,我对序数排序很熟悉,但这并不意味着我会使用它来呈现给用户的数据。

以上是关于是否有充分的理由对字符串使用文化敏感的比较器?的主要内容,如果未能解决你的问题,请参考以下文章

是否有充分的理由在单平台系统上使用 .proto 文件?

是否有充分的理由为 DialogFragments 使用子片段管理器?

在 2017 年使用 Meteor 有充分的理由吗? [关闭]

是否有任何陷阱或充分的理由不使用 autosproc 进行存储过程调用?

JavaScript:与文化无关、不区分大小写的字符串比较

是否有充分的理由在 Program.cs/main 中编写代码而不是使用类? [关闭]