web-dev-qa-db-ja.com

GUIDと文字列の比較

Googleでもここでも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?

pdate:この質問を説得力のあるものにするために、sidconst...に変更しました。Guid constを使用できないため、これは私が扱っている本当の問題。

13
Serj Sagan

Guidsを文字列として比較しないでください。また、既存の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倍のコストがかかります。値。

14
D Stanley

Dスタンレーの詳細

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()が推奨されるオプションです。

0
Kevin V