8

のソースコードを読んでEqualityComparer<T>.Defaultいて、それほど賢くないことがわかりました。次に例を示します。

enum MyEnum : int { A, B }
EqualityComparer<MyEnum>.Default.Equals(MyEnum.A, MyEnum.B)
//is as fast as 
EqualityComparer<int>.Default.Equals(0, 1)

enum AnotherEnum : long { A = 1L, B = 2L }
//is 8x slower than
EqualityComparer<long>.Default.Equals(1L, 2L)

その理由は、EqualityComparer のプライベート メソッドのソース コードから明らかです。

private static EqualityComparer<T> CreateComparer()
{
    //non-important codes are ignored
    if (c.IsEnum && (Enum.GetUnderlyingType(c) == typeof(int)))
    {
        return (EqualityComparer<T>) RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType) typeof(EnumEqualityComparer<int>), c);
    }
    return new ObjectEqualityComparer<T>();
}

を見てEqualityComparer<int>.Default、メソッドが次のような賢明な比較子を取得EqualityComparer<MyEnum>.Defaultできます。EqualityComparer<long>.DefaultEquals

public static bool Equals(int x, int y)
{
    return x == y;  //or return x.Equals(y); here 
                    //I'm not sure, but neither causes boxing
}

public static bool Equals(MyEnum x, MyEnum y)
{
    return x == y;  //it's impossible to use x.Equals(y) here 
                    //because that causes boxing
}

上記の 2 つは賢いですが、EqualityComparer<AnotherEnum>.Default不運です。最終的に確認できるメソッドから、 が得られますObjectEqualityComparer<T>()。そのEqualsメソッドはおそらく次のようになります。

public static bool Equals(AnotherEnum x, AnotherEnum y)
{
    return x.Equals(y);   //too bad, the Equals method is from System.Object
                       //and it's not override, boxing here!
                       //that's why it's so slow
}

Enum.GetUnderlyingType(c) == typeof(int)この条件は無意味だと思います。列挙型の基になる型が int 型の場合、メソッドはint のデフォルトの比較子をこの列挙型に変換できます。しかし、なぜ long に基づく列挙型を使用できないのでしょうか? そんなに難しくないですよね?何か特別な理由は?のような比較子を構築するx == yことは、列挙型にとってそれほど難しくありませんよね? ついにObjectEqualityComparer<T>列挙型の速度が低下するのはなぜですか(正しく動作しても)?

4

1 に答える 1

7

担当チームがこの機能を追加する説得力のある理由はまったくないと思います。すべての機能には実装コストがかかります。これには、(とりわけ) ドキュメント、コード、およびテストの時間が含まれます。

これまでのところ、この特定の機能が他の機能よりも選ばれていない理由はいくつかあります (そして、おそらく IMO に選ばれることはないでしょう):

  • 非常に狭いシナリオにのみ適用されます(enums以外のものに裏打ちされたものを比較しint、それを内部ループで実行します)
  • 問題が発生した場合は、非常に簡単で発見可能な解決策があります(独自の比較子を作成してください)
于 2011-04-29T08:34:28.007 に答える