Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How expensive is a GUID cast and comparison vs a string comparison

Tags:

c#

which would be faster?

bool same=(Guid)Identifier==id;

bool same=String.Equals(string1,string2, StringComparison.OrdinalIgnoreCase);
like image 620
zsharp Avatar asked Jan 22 '10 20:01

zsharp


People also ask

Are string comparisons expensive?

Comparing two strings is very slow and expensive. Most algorithms require iterating through entire string and matching each character. Here, the worst case algorithm will compare 4 bits. As you can see, there's a lot more going around for String comparison.

How do you compare GUIDs?

The CompareTo method compares the GUIDs as if they were values provided to the Guid constructor, as follows: It compares the Int32 values, and returns a result if they are unequal. If they are equal, it performs the next comparison. It compares the first Int16 values, and returns a result if they are unequal.

What is a string comparison?

string= compares two strings and is true if they are the same (corresponding characters are identical) but is false if they are not. The function equal calls string= if applied to two strings. The keyword arguments :start1 and :start2 are the places in the strings to start the comparison.

How is string comparison done?

The algorithm to compare two strings is simple: Compare the first character of both strings. If the first character from the first string is greater (or less) than the other string's, then the first string is greater (or less) than the second. We're done.


5 Answers

I used this code:

object victim = Guid.Empty;
Guid target = Guid.NewGuid();

Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000000; i++){
    bool equal = ((Guid) victim) == target;
}
Console.WriteLine("Direct cast   : {0}", sw.Elapsed);

sw.Reset(); sw.Start();
for (int i = 0; i < 10000000; i++)
{
    bool equal = Guid.Equals(victim, target);
}
Console.WriteLine("Guid.Equals   : {0}", sw.Elapsed);

sw.Reset(); sw.Start();
string a = victim.ToString(); // as suggested by Mikael
string b = target.ToString();
for (int i = 0; i < 10000000; i++)
{
    bool equal = String.Equals(a, b, StringComparison.OrdinalIgnoreCase);
}
Console.WriteLine("String.Equals : {0}", sw.Elapsed);

Console.ReadLine();

And got this result for different values (best scenario):

object victim = Guid.Empty;
Guid target   = Guid.NewGuid();
// Direct cast   : 00:00:00.1164198
// Guid.Equals   : 00:00:02.1268147
// String.Equals : 00:00:00.4129527  // oh my!

And this result for same value (worse scenario)

object victim = Guid.Empty;
Guid target   = Guid.Empty;
// Direct cast   : 00:00:00.2793173
// Guid.Equals   : 00:00:03.5625948
// String.Equals : 00:00:01.7564302
like image 58
Rubens Farias Avatar answered Oct 17 '22 01:10

Rubens Farias


In my testing doing a straight UUID-UUID comparison VS String-String comparison, the UUID comparison takes about 1/4 the time as the String comparison.

However, the casting of String->UUID is expensive. Much more expensive than the UUID->String conversion. Both are more expensive than either of the comparison methods.

So: If you've got two UUIDs compare the UUIDs directly. If you've got two Strings compare the Strings directly. If you've got one String and one UUID, convert the UUID to a String and compare the Strings.

like image 27
Michael Krauklis Avatar answered Oct 17 '22 02:10

Michael Krauklis


A Guid == Guid will use code like:

public bool Equals(Guid g)
{
if (g._a != this._a)
{
    return false;
}
if (g._b != this._b)
{
    return false;
}

while the string compare in your example will use an unsafe pointer comparison.

Without benchmarking it, I suspect the Guid will be faster, but we're talking marginal. And you really need to crank up the number of comparisons to the multi millions for it to matter.

Both comparisons will break out early, meaning left to right, so that will also impact the speed. The string compare has more checks before the comparison occurs and one more method call as well.

like image 27
Mikael Svenson Avatar answered Oct 17 '22 02:10

Mikael Svenson


A GUID compare is a memcmp of 16 bytes. It isn't going to be worse worse than a string compare, but if you care about performance that much you shouldn't be using managed code.

like image 36
John Knoeller Avatar answered Oct 17 '22 00:10

John Knoeller


.NET Guid is a 16 byte structure which when represented as a string will be formatted in this pattern "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" which is about 32 characters.

So represented as a GUID it would take 16 bytes and represented as a string it would take 32*2 = 64 bytes.

So GUID.Equals() should perform better.

Also GUID.Equals(GUID) would perform better then guid1 == guid2 because there is no boxing involved in the former.

like image 1
Santhosh Avatar answered Oct 17 '22 02:10

Santhosh