views:

936

answers:

8

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.

A: 

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.

womp
I checked out the post. Thanks, it was useful. It just reaffirmed that string.length is the fastest way to check if a string is empty, unless I misunderstood the benchmark results.
Jagd
+9  A: 

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.

Dario
The OP wasn't asking about which is the clearest way to write a string comparison. What's clear to one may not be clear to another.
The Beaver
Downvoters: Please comment on why you do so.
Dario
+2  A: 

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.

Konrad Rudolph
+1  A: 

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.

tanascius
A: 

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.

David B
A: 

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.

Joe
+5  A: 

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.

Nick Berardi
A: 

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

Roy Marco Aruta