1. ホーム
  2. .net

[解決済み] LINQクエリでToList()とToArray()のどちらを呼び出すのが良いですか?

2022-03-17 02:48:38

質問

クエリを宣言した直後に、そのクエリを評価したいケースによく遭遇します。これは通常、複数回繰り返し処理を行う必要があるためです。 は、計算コストが高い。例えば

string raw = "...";
var lines = (from l in raw.Split('\n')
             let ll = l.Trim()
             where !string.IsNullOrEmpty(ll)
             select ll).ToList();

これは問題なく動作します。 しかし もし、結果を変更しないのであれば、私はむしろ ToArray() ではなく ToList() .

しかし ToArray() は、最初に ToList() を呼び出すだけよりもメモリ効率が悪くなります。 ToList() .

私はおかしいのでしょうか?を呼び出せばいいのでしょうか? ToArray() - メモリが2回割り当てられることはないという知識で、安全かつ確実に?

どのように解決するのですか?

他の制約を満たすために単に配列が必要な場合以外は ToList . 大半のシナリオでは ToArray よりも多くのメモリを確保することになります。 ToList .

どちらもストレージにアレイを使用していますが ToList には、より柔軟な制約があります。 それは、配列が少なくともコレクションの要素数と同じ大きさである必要があることです。 もし配列がもっと大きくても問題はありません。 しかし ToArray は、配列が要素数通りの大きさである必要があります。

この制約を満たすために ToArray よりも1つ多くアロケーションを行うことが多い。 ToList . 十分な大きさの配列ができると、ちょうど適切な大きさの配列を確保し、その配列に要素をコピーして戻します。 これを回避できるのは、配列の成長アルゴリズムが、格納する必要のある要素数と偶然一致した場合だけです(間違いなく少数派です)。

EDIT

の中に余分な未使用メモリがあることの影響について、何人かの人から質問を受けました。 List<T> の値です。

これは有効な懸念事項です。 作成されたコレクションが長寿命で、作成後に変更されることがなく、Gen2ヒープに格納される可能性が高い場合は、余分なアロケーションを取る方が良い場合があります。 ToArray を前面に押し出しています。

しかし、一般的には、このようなケースは稀だと思います。 それよりも、より一般的なのは、多くの ToArray を呼び出すと、すぐに他の短時間のメモリ使用に回され、その場合 ToList の方が明らかに優れています。

ここで重要なのは、プロファイリング、プロファイリング、そしてさらにプロファイリングすることです。