2

2 つの文字列を比較する以下のコード サンプルで、パフォーマンスの最適化はありますか?

初め:

public static bool Compare_01()
{
    string str_01 = "a";
    string str_02 = "a";

    if (str_01 == str_02)
        return true;
    else
        return false;
}

二:

public static bool Compare_02()
{
    string str_01 = "a";
    string str_02 = "a";

    if ((object)str_01 == (object)str_02)
        return true;
    else
        return false;
}

両方とも戻るtrue

彼らのilコードには1つだけ違いがあります:

1位:

IL_0001:  ldstr       "a"
IL_0006:  stloc.0     // str_01
IL_0007:  ldstr       "a"
IL_000C:  stloc.1     // str_02
IL_000D:  ldloc.0     // str_01
IL_000E:  ldloc.1     // str_02
IL_000F:  call        System.String.op_Equality

2番目:

IL_0001:  ldstr       "a"
IL_0006:  stloc.0     // str_01
IL_0007:  ldstr       "a"
IL_000C:  stloc.1     // str_02
IL_000D:  ldloc.0     // str_01
IL_000E:  ldloc.1     // str_02
IL_000F:  ceq         

System.Stringで次のようなものを見つけました:

public static bool Equals(String a, String b) {
    // Here
    if ((Object)a==(Object)b) {
        return true;
    }
    // ****

    if ((Object)a==null || (Object)b==null) {
        return false;
    }

    if (a.Length != b.Length)
        return false;

    return EqualsHelper(a, b);
}
4

3 に答える 3

7

あなたのバージョン「Two」は何か違うことをします:参照の等価性を比較します(これはceq、編集で追加した IL で確認できます)。これは、文字列のインターンにより、基本的なテストで機能することがよくありますが、依存するべきではありません。それは偶然にのみ働いています。

基本的に、次を使用します。

return str_01 == str02;

これは、「これら 2 つの文字列が等しいかどうかを比較する」という表現の慣用的な方法であり、string.Equals(string a, string b) anywayの呼び出しにインライン化されます。

于 2014-12-19T09:09:30.440 に答える
4

参照の比較は高速ですが、文字列は同じインスタンスでなくても同じ値を持つことができます。比較は異なることを行うため、文字列比較の最適化として参照比較を使用することはできません。

同じ値を持つが同じインスタンスではない 2 つの文字列を比較すると、違いがわかります。

string str_01 = "ab";
string str_02 = String.Concat("a", "b");

Console.WriteLine(str_01 == str_02);
Console.WriteLine((object)str_01 == (object)str_02);

出力:

True
False

このString.Equalsメソッドは、実際には同じインスタンスである 2 つの文字列を比較する場合に、参照比較を使用してケースをキャッチします。文字列が別々のインスタンスである場合、文字列の値を比較します。

于 2014-12-19T09:19:33.527 に答える
3

メソッドCompare_01()Compare_02()は同じことをしていません。最初のものは、後で参照を比較しながら、文字列値を比較しています。JIT とランタイムが文字列を作成しa、同じアドレスを両方の変数に割り当てるため、どちらも true を返します。

各文字列リテラルが必ずしも新しい文字列インスタンスになるとは限りません。文字列等値演算子 (セクション 7.9.7) に従って等価である 2 つ以上の文字列リテラルが同じアセンブリにある場合、これらの文字列リテラルは同じ文字列インスタンスを参照します。たとえば、MSDNによって生成された出力

class Test 
{    static void Main() {
      object a = "hello";
      object b = "hello";
      System.Console.WriteLine(a == b);    
     } 
}

bool値を比較したい場合は、(true または false)である式の結果を単純に返さないでください。

public static bool CompareStr(String str1 , String str2)
{
      return str1 == str2;
}
于 2014-12-19T09:09:01.613 に答える