通用列表性能优化

Ala*_*n B 4 c# linq generics optimization

我正在尝试优化通用列表算术运算.我有3个可空双重列表,如下所述.

List<double?> list1 = new List<double?>();
List<double?> list2 = new List<double?>();
List<double?> listResult = new List<double?>();

int recordCount = list1.Count > list2.Count ? list2.Count : list1.Count;

for (int index = 0; index < recordCount; index++)
{
      double? result = list1[index] + list2[index];
      listResult.Add(result);
}
Run Code Online (Sandbox Code Playgroud)

如果我有庞大的列表,有没有办法让这个操作运行得更快?

感谢您的输入.

Ree*_*sey 9

如果我有庞大的列表,有没有办法让这个操作运行得更快?

您可以将结果的列表创建移动到计数之后:

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);
Run Code Online (Sandbox Code Playgroud)

这将允许您指定结果所需的确切容量,并避免在列表本身内重新分配.对于"巨大的列表",这可能是最慢的部分之一,因为内存分配和列表变大的副本将是这里最慢的操作.

此外,如果计算很简单,您可能会使用多个核心:

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;
    });
Run Code Online (Sandbox Code Playgroud)

鉴于"工作"在这里非常简单,您可能实际上需要一个自定义分区器来充分利用并行性(有关详细信息,请参阅如何:加速小型循环体):

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];
        }
    });
Run Code Online (Sandbox Code Playgroud)

但是,如果这不是瓶颈,您可以使用LINQ将其作为单行代码:

var results = list1.Zip(list2, (one, two) => one + two).ToList();
Run Code Online (Sandbox Code Playgroud)

但是,如果性能确实是一个瓶颈,这将(非常轻微)低于自己处理循环的效率.