Search code examples
c#stringcomparisonguid

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.


Solution

  • 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 do 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.