Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Guid with string

I'm surprised that I couldn't find an answer to this either in Google or here on SO, but what is the best way to compare a string to Guid taking into consideration case, and, if appropriate, performance

const string sid = "XXXXX-...."; // This comes from a third party library
Guid gid = Guid.NewGuid(); // This comes from the db

if (gid.ToString().ToLower() == sid.ToLower())

if (gid == new Guid(sid))

// Something else?

Update: To make this question more compelling, I changed sid to a const... and since you can't have a Guid const this is the real problem I am dealing with.

like image 546
Serj Sagan Avatar asked Jun 27 '16 21:06

Serj Sagan


People also ask

How to compare Guid with string c#?

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.

Can you convert GUID to string?

According to MSDN the method Guid. ToString(string format) returns a string representation of the value of this Guid instance, according to the provided format specifier. Examples: guidVal.

Are GUIDs always the same length?

So the answer is "yes", it will always be the same length. As for the 4, it is a version number (according to http://en.wikipedia.org/wiki/Uuid). Every GUID that you generate with that algorithm will have a 4 in that position, but older GUIDs will have a 1, 2, or 3.

What is an empty guid?

You can use Guid.Empty . It is a read-only instance of the Guid structure with the value of 00000000-0000-0000-0000-000000000000. you can also use these instead. var g = new Guid(); var g = default(Guid);


1 Answers

Don't compare Guids as strings, and don't create a new Guid from a string just to compare it to an existing Guid.

Performance aside, there is not a single standard format for representing a Guid as a string, so you run the risk of comparing incompatible formats, and you have to ignore case, either by configuring String.Compare to do so or converting each to lower case.

A much more idiomatic and performant way is to create a static, readonly Guid from the constant string value and to all comparisons using native Guid equality:

const string sid = "3f72497b-188f-4d3a-92a1-c7432cfae62a";
static readonly Guid guid = new Guid(sid);

void Main()
{
    Guid gid = Guid.NewGuid(); // As an example, say this comes from the db

    Measure(() => (gid.ToString().ToLower() == sid.ToLower()));
    // result: 563 ms

    Measure(() => (gid == new Guid(sid)));
    // result: 629 ms

    Measure(() => (gid == guid));
    // result: 10 ms

}

// Define other methods and classes here
public void Measure<T>(Func<T> func)
{
    Stopwatch sw = new Stopwatch();

    sw.Start();
    for(int i = 1;i<1000000;i++)
    {
        T result = func();
    }
    sw.Stop();

    Console.WriteLine(sw.ElapsedMilliseconds);
}

So string comparison and creating a new Guid from the constant value are 50-60 times more expensive than comparing the Guid to a static, read-only Guid created from the constant value.

like image 111
D Stanley Avatar answered Sep 21 '22 21:09

D Stanley