C#中的字符串比较性能
有许多方法可以比较字符串。 通过单一方式获得性能提升吗?
我总是选择像这样比较字符串:
string name = "Bob Wazowski"; if (name.CompareTo("Jill Yearsley") == 0) { // whatever... }
但我发现很少有人这样做,如果有的话,我看到更多的人只是做一个直接的==比较,据我所知,这是比较字符串的最差方式。 我错了吗?
另外,它是如何比较LINQ查询中的字符串的? 例如,我喜欢做以下事情:
var results = from names in ctx.Names where names.FirstName.CompareTo("Bob Wazowski") == 0 select names;
但同样,我看到很少有人在他们的LINQ查询中进行字符串比较。
根据Reflector
"Hello" == "World"
是相同的
String.Equals("Hello", "World");
它基本上确定它们是否是同一个引用对象,如果它们中的任何一个为null,如果一个为null而另一个为null则为自动false,然后比较不安全循环中的每个字符。 因此它根本不关心文化规则,这通常不是什么大问题。
和
"Hello".CompareTo("World") == 0
是相同的
CultureInfo.CurrentCulture.CompareInfo.Compare("Hello", "World", CompareOptions.None);
就function而言,这基本上是相反的。 它将字符串输入到上下文中考虑了文化,编码和其他所有内容。
所以我想象String.CompareTo比相等运算符慢几个数量级 。
对于LINQ而言,如果使用LINQ-to-SQL并不重要,因为两者都会生成相同的SQL
var results = from names in ctx.Names where names.FirstName.CompareTo("Bob Wazowski") == 0 select names;
的
SELECT [name fields] FROM [Names] AS [t0] WHERE [t0].FirstName = @p0
所以你真的没有为LINQ-to-SQL获得任何东西,除了更难阅读代码和可能更多的表达式解析。 如果你只是使用LINQ作为标准数组的东西,那么我上面列出的规则就适用了。
在我看来,你应该总是使用最清晰的方式,即使用==
!
这可以直接理解:当“你好”等于“世界”然后做点什么。
if ("Hello" == "World") // ...
在内部,调用String::Equals
,为此目的明确存在 – 比较两个字符串是否相等。 (这与指针和引用等无关)
这里不是立即清楚 – 为什么比较为零?
if ("Hello".CompareTo("World") == 0)
.CompareTo不仅仅用于检查相等性(你有==) – 它比较两个字符串。 您可以使用.CompareTo来确定一个字符串比另一个字符串“更大”。 你可以检查是否相等,因为对于相等的字符串它会产生零,但这不是它的概念。
因此,有不同的方法和接口用于检查相等性(IEquatable,operator ==)和比较(IComparable)
Linq与常规C#的行为不同。
阅读杰夫的最佳代码完全没有代码 。 foo.CompareTo(bar) == 0
:可怕的视觉混乱。 占用大量空间并没有传达任何有趣的意义。 事实上,它强调了许多无关紧要的东西,这些东西会将注意力从真正的问题上转移开。
如果使用这个较长的变体没有明确的原因,请不要。
至于性能:这对于这个简单的情况来说无关紧要。 如果相等运算符==
应该比CompareTo
表现更差,请随时向Microsoft提交错误报告。 这绝不可能发生。
MSDN声明你应该根据你需要执行的任务使用比较函数:
CompareTo方法主要用于排序或字母顺序操作。 当方法调用的主要目的是确定两个字符串是否相等时,不应该使用它。 要确定两个字符串是否相等,请调用Equals方法。
因此,如果它不是关于排序和retrun值不重要我会说应该使用:
first.Equals(second)
或者如果比较是文化特定的,例如在德语等语言中:
String.Equals(first, second, StringComparison.CurrentCulture)
看看这些链接:
如何:比较字符串(C#编程指南)
String.CompareTo方法(对象)
最近关于修剪字符串的最快方法有一个非常类似的问题,但它基本上是对不同比较方法的基准测试。
你可以查看这篇文章的基准。
有一篇很好的文章比较.NET中的平等价值:身份和等价 ,这比仅仅进行字符串比较更为通用,但非常有趣。
如果相等运算符实际上比CompareTo
表现更差 – 微软是否会使相等运算符的实现调用CompareTo
?
只需使用相等运算符来测试相等性。
我通常使用带有StringComparison参数的重载的String.Compare,因为那时我可以绝对明确比较是否区分大小写和文化敏感。 这需要.NET 2.0或更高版本。
对于非文化敏感的比较,最快的是StringComparison.Ordinal(或StringComparison.OrdinalIgnoreCase,如果不区分大小写)。
使用==的问题在于,作者已经考虑了案例和文化敏感性并不清楚。
这里有关于这个主题的MSDN文章很好。
要在C#中比较string
的最佳方法是使用a.Equals(b)
,其中a和b是字符串。 这是比较字符串的最佳方法,因为它比较了对象a和b的值,并且不依赖于对象的引用。
如果您要使用“ ==
”符号,如果两个对象具有相同的引用,则结果将相等,但如果它们具有不同的引用并且具有相同的值,则会出现问题。
如果您测试另一个字符串是否在另一个字符串的相同位置之前,之后或出现在另一个字符串的相同位置,其中它将分别返回负值,正值或零值,则compareTo
方法是最佳使用方法。 如果参数为null
它也将返回正值
这是我发现的最完整,最有帮助的MSDN指南,用于字符串比较。
使用与StringComparison.Ordinal或StringComparison.OrdinalIgnoreCase的比较可获得更好的性能。