3

列挙型があるとします。例えば

enum MyEnum
{ 
    Item1, 
    Item2, 
    Item3
}

列挙型の各項目に対して何かを「キャッシュ」したい。だから私には2つの選択肢があります。

辞書オプション:

Dictionary<MyEnum, /*someStructure*/> cache = new Dictionary<MyEnum, /*someStructure*/>>();

または配列オプション:

/*someStructure*/[] cache = new /*someStructure*/[Enum.GetValues(typeof(MyEnum)).Length]

これらの各オプションの長所と短所は何ですか? 私の意見では、Dictionaryオプションは読みやすく使いやすいですが、Arrayオプションよりも遅いです。

しかし、Dictionary実際には遅くなるでしょうか?がキーとして使用される場合、「配列」だけを基になる実装として使用できることDictionaryを理解するのに十分なほど「スマート」でしょうか?enum

問題は、「醜いarrayオプション」は「単純な」Dictionaryオプションよりも高速になるかということです。多分私はそれをテストすることができます...しかし、私が質問を書いたとき、私は他の人がどう思うか知りたいです.

4

2 に答える 2

4

Dictionany<TKey, TValue>「スマート」ではなく、特定のキーに対して最適化されません。根底にある実装は常に同じです。

ただし、パフォーマンスについては、enum値をディクショナリのキーとして使用すると、予想よりもはるかに遅くなり、キーとして格納するよりもはるかに遅くなりInt32ます。これは、ランタイムが を呼び出すときに列挙型のハッシュ コードを取得するために、大量のリフレクションを使用するためGetHashCode()です。これは、実際には非常に奇妙であることがわかりました。

しかし、最も読みやすいアプローチ (列挙型を辞書のキーとして使用する) が十分に高速な場合、これらすべては問題になりません。そして、ここにいる誰もその質問に答えることはできません. これを測定する必要があります。時期尚早の最適化を行わず、ソリューションが状況に応じて十分に高速ではないことが証明されるまで (おそらくそうなるでしょう)、最も読みやすく、保守しやすいコードを使用してください。

ただし、配列に切り替える代わりに、Int32キーを使用して辞書に切り替えてみてください。

var dictionary = new Dictionary<int,  /*someStructure*/>();

dictionary[(int)MyEnum.Item1] = /*new someStructure()*/;
于 2012-11-17T10:52:06.750 に答える
1

これは主観的な答えですが、個人的には次の場合に辞書よりも配列を使用します。

  1. すべての列挙メンバーの基になる値は連続しています。次のように、値の間に大きなギャップがある場合、配列の使用は直感的ではありません (そしてメモリを浪費します)。

    enum MyEnum { Units, Tens = 10, Hundreds = 100, }

  2. すべての列挙メンバーは、常に構造体に値を持ちます。そうでない場合、ディクショナリは、そのTryGetValueメソッドを通じて特定のキーの存在をチェックするためのより直感的なセマンティクスを提供します。(とはnullいえ、値が参照型である場合は、不在を示すために代わりに使用できます。)

于 2012-11-17T10:53:29.803 に答える