正在将Guid与字符串进行比较

本文关键字:比较 字符串 Guid | 更新日期: 2023-09-27 17:51:21

我很惊讶,我在谷歌或SO上都找不到答案,但考虑到情况和性能,比较stringGuid的最佳方法是什么

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?

更新:为了使这个问题更有说服力,我将sid更改为const。。。既然你不能有Guid const,这就是我正在处理的真正问题。

正在将Guid与字符串进行比较

不要将Guid s作为字符串进行比较,也不要从字符串创建新的Guid只是为了将其与现有的Guid进行比较。

撇开性能不谈,没有一种标准格式可以将Guid表示为字符串,因此您可能会比较不兼容的格式,并且必须忽略大小写,方法是将String.Compare配置为这样做,或者将每个格式转换为小写。

一种更惯用和更具性能的方法是从常量字符串值创建一个静态只读Guid,并使用本机Guid等式进行所有比较:

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);
}

因此,字符串比较和根据常数值创建新的Guid的成本是将Guid与根据常数值生成的静态只读Guid进行比较的50-60倍。

详细阐述D Stanley

const string sid = "3f72497b-188f-4d3a-92a1-c7432cfae62a";
static readonly Guid guid = new Guid(sid);
static void Main()
{
    Guid gid = Guid.NewGuid(); // As an example, say this comes from the db
    Measure(() => (gid.ToString().ToLower() == sid.ToLower()));
    // result: 177 ms
    Measure(() => (gid == new Guid(sid)));
    // result: 113 ms
    Measure(() => (gid == guid));
    // result: 6 ms
    Measure(() => (gid == Guid.Parse(sid)));
    // result: 114 ms
    Measure(() => (gid.Equals(sid)));
    // result: 7 ms
}
// Define other methods and classes here
public static void Measure<T>(Func<T> func)
{
    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();
    for (int i = 1; i < 1000000; i++)
    {
        T result = func();
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
}

因此,如果不能将guid存储在常量中,则首选内置guid.Equals((。