繰り返して数える必要があります。 ToArray()またはToList()で最速または優先されるものは何ですか? [複製]
-
22-07-2019 - |
質問
次のようなコードがあります:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ?
foreach(var item in t)
{
..
}
var j = t.Count; // also I need this
}
どの方法が推奨されますか
何もせずに行くことができますが、サイズを知る必要があり、 Enumerable.Count&lt; T&gt;()
を呼び出したくありません- Array&lt ; T&gt; .Size
または List&lt; T&gt; .Count
。私は正しいですか?
解決
実際には、Count(IEnumerable)の現在のMS実装には、IEnumerableがICollectionであり、Countを呼び出すかどうかを調べるショートカットがあります。したがって、要素をカウントする場合のパフォーマンスは匹敵するはずです。
ToListとToArrayは少し同じです。 IEnumerableがICollectionの場合、代わりにCopyToメソッドが呼び出されます。これは少し高速です。
したがって、コードを最も読みやすくするものを選択し、明確な答えを得るためにユースケースのベンチマークを行います。
更新: 素朴なベンチマークを行いました。
配列から開始: var items = Enumerable.Range(1,1000).ToArray();
- ToList()の呼び出し:25ms / 10000
- ToArray()の呼び出し:23ミリ秒/ 10000
IEnumerableで開始: var items = Enumerable.Range(1,1000);
- ToList()の呼び出し:168ms / 10000
- ToArray()の呼び出し:171 ms / 10000
つまり、基本的には同等のパフォーマンスが得られます。
他のヒント
パフォーマンスが本当に 心配な場合は、 IEnumerable
をループして、カウントします。これにより、新しいコレクションを完全に作成する必要がなくなり、交差点を1回繰り返すだけで済みます。
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys);
int count = 0;
foreach(var item in t)
{
count++;
..
}
var j = count;
}
しかし、他の誰かが言ったように、これは微最適化の匂いです。この状況でパフォーマンスが本当に重要な場合は、少なくともパフォーマンスプロファイリングを行って、どのメソッドが本当にあなたにとって最も速いかを見つけてください。
違いはおそらく非常に小さいため、ニーズに合った方法を使用するだけの価値があります。マイクロ最適化の匂い。
そしてこの場合、あなたがしているのはセットを列挙してセットをカウントするだけなので(どちらもIEnumerableで実行できます)、なぜそれをIEnumerable&lt;&gt;のままにしないのですか?