是否有充分的理由对字符串使用文化敏感的比较器?
Is there a good reason to use a culture-sensitive comparer for strings?
在深入研究 .NET 代码后,我发现 Comparer<string>.Default
生成的比较器和 string.CompareTo
的实现使用了区分文化的字符串比较(具体来说,对 CultureInfo.CurrentCulture
敏感).有序集和映射的默认行为是使用此比较器。
但是,F# 的有序 Set
和 Map
为使用 String.CompareOrdinal
的字符串创建了一个特殊的比较器。因此,这些集合在使用字符串键时比最近的 System.Collections.Immutable
排序字典和排序映射要快得多,如下图所示:
我也在开发一个不可变集合库(在图表中称为 Funq)。在执行此优化之前,我遇到了与那些集合相同的性能问题。
考虑到我确实希望在有序集合中保持预期的顺序,此优化会导致任何问题吗?您能否举出在特定文化中行为不符合预期的具体示例?
当然可以:
"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));
在深入研究 .NET 代码后,我发现 Comparer<string>.Default
生成的比较器和 string.CompareTo
的实现使用了区分文化的字符串比较(具体来说,对 CultureInfo.CurrentCulture
敏感).有序集和映射的默认行为是使用此比较器。
但是,F# 的有序 Set
和 Map
为使用 String.CompareOrdinal
的字符串创建了一个特殊的比较器。因此,这些集合在使用字符串键时比最近的 System.Collections.Immutable
排序字典和排序映射要快得多,如下图所示:
我也在开发一个不可变集合库(在图表中称为 Funq)。在执行此优化之前,我遇到了与那些集合相同的性能问题。
考虑到我确实希望在有序集合中保持预期的顺序,此优化会导致任何问题吗?您能否举出在特定文化中行为不符合预期的具体示例?
当然可以:
"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));