C# 中的字符串比较性能

发布于 2024-07-20 06:02:55 字数 520 浏览 7 评论 0原文

有多种方法可以比较字符串。 采取一种方式比另一种方式是否能带来性能提升?

我总是选择像这样比较字符串:

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 查询中像这样进行字符串比较。

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:

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

入画浅相思 2024-07-27 06:02:56

根据 Reflector 的说法

"Hello" == "World"

,它

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

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

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

功能而言,这基本上是相反的

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

。 它考虑了文化、编码以及上下文中字符串的所有其他内容。

所以我可以想象 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 用于标准数组,那么我上面列出的规则就适用。

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.

as for your LINQ it doesn't matter if you are using LINQ-to-SQL because both will generate the same 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.

病毒体 2024-07-27 06:02:56

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

这可以直接理解为:当“Hello”等于“World”时,则做某事。

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

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

这并不是立即清楚的 - 为什么与零比较?

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

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

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

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

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.

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

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

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 can check for equality because it yield zero for equal strings, but that's not what it's concepted for.

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

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

浮萍、无处依 2024-07-27 06:02:56

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

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

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

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.

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.

烂人 2024-07-27 06:02:56

MSDN 指出您应该根据需要执行的任务使用比较函数:

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

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

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

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

请查看以下链接:

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

String.CompareTo 方法(对象)

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

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.

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:

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

Take a look a these links:

How to: Compare Strings (C# Programming Guide)

String.CompareTo Method (Object)

岁月苍老的讽刺 2024-07-27 06:02:56

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

您可以查看基准关于这篇文章

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.

木格 2024-07-27 06:02:56

有一篇不错的文章 比较 .NET 中的相等值:同一性和等价性这比字符串比较更通用一些,但仍然非常有趣。

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

源来凯始玺欢你 2024-07-27 06:02:56

如果相等运算符的性能实际上比 CompareTo 差 - Microsoft 不会调用 CompareTo 来实现相等运算符吗?

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

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

Just use the equality operator to test for equality.

春庭雪 2024-07-27 06:02:56

这里是最完整、最有帮助的 MSDN我找到的字符串比较指南。

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

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

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

不打扰别人 2024-07-27 06:02:56

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

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

使用 == 的问题在于,不清楚作者是否考虑了大小写和文化敏感性。

此处有一篇关于该主题的很好的 MSDN 文章。

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.

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

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.

策马西风 2024-07-27 06:02:56

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

如果您要使用 "==" 符号,则如果两个对象具有相同的引用,结果将相等,但当它们具有不同的引用时,就会出现问题并具有相同的值。

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

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

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 compareTo method 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文