C#中的字符串比较性能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/859005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:32:42  来源:igfitidea点击:

String comparison performance in C#

c#.netlinqperformancestring-comparison

提问by Jagd

There are a number of ways to compare strings. Are there performance gains by doing one way over another?

有多种比较字符串的方法。通过一种方式比另一种方式有性能提升吗?

I've always opted to compare strings like so:

我一直选择像这样比较字符串:

string name = "Bob Wazowski";
if (name.CompareTo("Jill Yearsley") == 0) {
    // whatever...
}

But I find few people doing this, and if anything, I see more people just doing a straight == comparison, which to my knowledge is the worst way to compare strings. Am I wrong?

但是我发现很少有人这样做,如果有的话,我看到更多的人只是直接进行 == 比较,据我所知,这是比较字符串的最糟糕的方法。我错了吗?

Also, does it make a difference in how one compares strings within LINQ queries? For example, I like to do the following:

此外,在 LINQ 查询中比较字符串的方式是否有所不同?例如,我喜欢执行以下操作:

var results = from names in ctx.Names
              where names.FirstName.CompareTo("Bob Wazowski") == 0
              select names;

But again, I see few people doing string comparisons like so in their LINQ queries.

但同样,我看到很少有人在他们的 LINQ 查询中像这样进行字符串比较。

采纳答案by Nick Berardi

According to Reflector

根据反射器

"Hello" == "World"

is the same as

是相同的

String.Equals("Hello", "World");

which basically determines if they are the same reference object, if either of them is null, which would be an automatic false if one was null and the other was not, and then compares each character in an unsafe loop. So it doesn't care about cultural rules at all, which usually isn't a big deal.

这基本上确定它们是否是相同的引用对象,如果它们中的任何一个为空,如果一个为空而另一个不是,则自动错误,然后比较不安全循环中的每个字符。所以它根本不关心文化规则,这通常没什么大不了的。

and

"Hello".CompareTo("World") == 0

is the same as

是相同的

CultureInfo.CurrentCulture.CompareInfo.Compare("Hello", "World", CompareOptions.None);

This is basically the opposite as far as functionality. It takes into consideration culture, encoding, and everything else with the string in to context.

就功能而言,这基本上是相反的。它考虑了文化、编码以及将字符串置于上下文中的所有其他内容。

So I would imagine that String.CompareTo is a couple of orders of magnitude slower than the equality operator.

所以我会想象String.CompareTo 比相等运算符慢几个数量级

as for your LINQ it doesn't matter if you are using LINQ-to-SQL because both will generate the same SQL

至于你的 LINQ,如果你使用 LINQ-to-SQL 并不重要,因为两者都会生成相同的 SQL

var results = from names in ctx.Names
          where names.FirstName.CompareTo("Bob Wazowski") == 0
          select names;

of

SELECT [name fields]
FROM [Names] AS [t0]
WHERE [t0].FirstName = @p0

so you really aren't gaining anything for LINQ-to-SQL except harder to read code and probably more parsing of the expressions. If you are just using LINQ for standard array stuff then the rules I laid out above apply.

所以你真的没有为 LINQ-to-SQL 获得任何好处,除了更难阅读代码和可能更多的表达式解析。如果您只是将 LINQ 用于标准数组内容,那么我上面列出的规则适用。

回答by womp

There was a pretty similar question recently regarding the fastest way to trim a string, but it was basically benchmarking the different ways of comparing them.

最近有一个非常相似的问题,关于修剪字符串的最快方法,但它基本上是对比较它们的不同方法进行基准测试。

You can check out the benchmarks on this post.

您可以查看这篇文章中的基准测试。

回答by Dario

In my opinion, you should always use the clearest way, which is using ==!

在我看来,您应该始终使用最清晰的方法,那就是使用==!

This can be understood directly: When "Hello" equals "World" then do something.

这可以直接理解:当“Hello”等于“World”时,就做点什么。

if ("Hello" == "World")
    // ...

Internally, String::Equalsis invoked which exists explicitly for this purpose - Comparing two strings for equality. (This has nothing to do with pointers and references etc.)

在内部,String::Equals为此目的显式存在调用 - 比较两个字符串的相等性。(这与指针和引用等无关。)

This here isn't immediately clear - Why compare to zero?

这在这里不是很清楚 - 为什么要与零比较?

if ("Hello".CompareTo("World") == 0)

.CompareTo isn't designed just for checking equality (you have == for this) - It compares two strings. You use .CompareTo in sorts to determine wheter one string is "greater" than another. You cancheck for equality because it yield zero for equal strings, but that's not what it's concepted for.

.CompareTo 不仅仅是为了检查相等性而设计的(你有 ==) - 它比较两个字符串。您在排序中使用 .CompareTo 来确定一个字符串是否比另一个“更大”。您可以检查相等性,因为它对相等的字符串产生零,但这不是它的概念。

Hence there are different methods and interfaces for checking equality (IEquatable, operator ==) and comparing (IComparable)

因此,有不同的方法和接口来检查相等性(IEquatable、operator ==)和比较(IComparable)

Linq doesn't behave different than regular C# here.

在这里,Linq 的行为与常规 C# 没有什么不同。

回答by Konrad Rudolph

Read Jeff's The Best Code is No Code at All. foo.CompareTo(bar) == 0: horrible visual clutter. Takes up a lot of space and conveys no interesting meaning. In fact, it emphasizes a lot of irrelevant stuff which deflects attention away from the real problem.

阅读 Jeff 的《最好的代码就是没有代码》foo.CompareTo(bar) == 0: 可怕的视觉混乱。占用大量空间,并没有传达任何有趣的含义。事实上,它强调了许多不相关的东西,从而转移了对真正问题的注意力。

If there's no well-defined reason for using this longer variant, don't.

如果没有明确的理由使用这个更长的变体,不要。

As for performance: it simply doesn't matter for this simple case. If the equality operator ==should really perform worse than CompareTo, feel free to file a bug report with Microsoft. This must not happen.

至于性能:对于这个简单的情况,这根本无关紧要。如果相等运算符的性能==确实比 差CompareTo,请随时向 Microsoft 提交错误报告。这绝不能发生。

回答by tanascius

There is a nice article Comparing Values for Equality in .NET: Identity and Equivalencewhich is a bit more general than only string comparison, but very interesting nevertheless.

有一篇不错的文章Comparing Values for Equality in .NET: Identity and Equivalence这比仅字符串比较更一般,但仍然非常有趣。

回答by Amy B

If the equality operator actually performed worse than CompareTo- wouldn't Microsoft make the implementation of the equality operator call CompareTo?

如果相等运算符的实际表现比CompareTo- 微软不会实现相等运算符调用CompareTo吗?

Just use the equality operator to test for equality.

只需使用相等运算符来测试相等性。

回答by Joe

I generally use String.Compare with the overload that takes a StringComparison parameter, because then I can be absolutely explicit about whether or not the comparison is case- and culture-sensitive. This needs .NET 2.0 or later.

我通常将 String.Compare 与采用 StringComparison 参数的重载一起使用,因为这样我就可以绝对明确地确定比较是否区分大小写和区域性。这需要 .NET 2.0 或更高版本。

The fastest is StringComparison.Ordinal (or StringComparison.OrdinalIgnoreCase if case-insensitive) for comparisons that are not culture-sensitive.

最快的是 StringComparison.Ordinal(或 StringComparison.OrdinalIgnoreCase,如果不区分大小写),用于不区分区域性的比较。

The problem with using == is that it's not clear that the author has considered case- and culture-sensitivity.

使用 == 的问题在于作者是否考虑了区分大小写和文化的问题尚不清楚。

There's a good MSDN article on the subject here.

有关于这个问题的一个很好的MSDN文章在这里

回答by Roy Marco Aruta

To best way to compare string's in C# is to use the a.Equals(b)where aand bare strings. This is the best way to compare string because it compares the values of the objects aand b, and does not depent on the reference of the objects.

为了比较最好的方法string的在C#中是使用a.Equals(b)其中一个b是字符串。这是比较字符串的最佳方式,因为它比较对象ab的值,并且不依赖于对象的引用。

If you're going to use "=="symbol, the result will be equal if both objects have the same reference but you will have a problem when they have different references and have the same value.

如果您打算使用" =="符号,如果两个对象具有相同的引用,则结果将相等,但是当它们具有不同的引用且具有相同的值时,您将遇到问题。

The compareTomethod is best way to use if your testing whether the other string is preceding, following or appearing in the same position of the other string wherein it will return negative value , positive value or zero value respectively. It will return also positive value if the parameter is null

compareTo如果您测试另一个字符串是在另一个字符串的前面、后面还是出现在另一个字符串的相同位置,则该方法是最好的使用方法,其中它将分别返回负值、正值或零值。如果参数是,它也将返回正值null

回答by CloudyMarble

Well MSDN states you shoul use the comparision function according to the task you need to perform:

那么 MSDN 声明你应该根据你需要执行的任务使用比较功能:

The CompareTo method was designed primarily for use in sorting or alphabetizing operations. It should not be used when the primary purpose of the method call is to determine whether two strings are equivalent. To determine whether two strings are equivalent, call the Equals method.

CompareTo 方法主要设计用于排序或按字母顺序排列的操作。当方法调用的主要目的是确定两个字符串是否相等时,不应使用它。若要确定两个字符串是否等效,请调用 Equals 方法。

So if its not about sorting and the retrun value is not important i would say one should use the:

因此,如果它不是关于排序并且重运行值不重要,我会说应该使用:

first.Equals(second)or if the comparison is culture specific for example in languages like in german:

first.Equals(second)或者如果比较是特定于文化的,例如在德语等语言中:

String.Equals(first, second, StringComparison.CurrentCulture)

String.Equals(first, second, StringComparison.CurrentCulture)

Take a look a these links:

看看这些链接:

How to: Compare Strings (C# Programming Guide)

如何:比较字符串(C# 编程指南)

String.CompareTo Method (Object)

String.CompareTo 方法(对象)

回答by Ognyan Dimitrov

Hereis the most complete and helpful MSDN guide for string comparison I have found.

是我找到的最完整和最有用的 MSDN 字符串比较指南。

Use comparisons with StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase for better performance.

使用 StringComparison.Ordinal 或 StringComparison.OrdinalIgnoreCase 进行比较以获得更好的性能。