巨大なリストがある場合、この操作をより速く実行する方法はありますか?
集計後まで、結果のリスト作成を移動できます。
List<double?> list1 = new List<double?>();
List<double?> list2 = new List<double?>();
int recordCount = list1.Count > list2.Count ? list2.Count : list1.Count;
List<double?> listResult = new List<double?>(recordCount);
これにより、結果に必要な正確な容量を指定し、リスト自体内での再割り当てを回避できます。「巨大なリスト」の場合、これはおそらく最も遅い部分の 1 つです。これは、リストが大きくなるにつれてメモリ割り当てとコピーがここで最も遅い操作になるためです。
また、計算が単純な場合は、複数のコアを使用できる可能性があります。
List<double?> list1 = new List<double?>();
List<double?> list2 = new List<double?>();
int recordCount = list1.Count > list2.Count ? list2.Count : list1.Count;
var results = new double?[recordCount]; // Use an array here
Parallel.For(0, recordCount, index =>
{
double? result = list1[index] + list2[index];
results[index] = result;
});
ここでの「作業」は非常に単純であるため、並列処理を最大限に活用するには、おそらく実際にはカスタム パーティショナーが必要になるでしょう (詳細については、「方法: 小さなループ本体を高速化する」を参照してください)。
var results = new double?[recordCount]; // Use an array here
var rangePartitioner = Partitioner.Create(0, recordCount);
Parallel.ForEach(rangePartitioner, range =>
{
for (int index = range.Item1; index < range.Item2; index++)
{
results[index] = list1[index] + list2[index];
}
});
ただし、これがボトルネックでない場合は、LINQ を使用してワンライナーでこれを行うことができます。
var results = list1.Zip(list2, (one, two) => one + two).ToList();
ただし、パフォーマンスが実際にボトルネックである場合、これはループを自分で処理するよりも (非常にわずかに) 効率が低下します。