Foreach Loop花费更多时间来处理

时间:2018-03-13 09:53:07

标签: c#

我有两个集合,有些条件是使用linq查询完成的。比较两个列表并从中获取结果。我使用了foreach循环和linq查询,这些集合有65000个数据,我的问题是它需要更多的时间来处理。我的代码如下所述。如何提高性能以及如何缩短处理时间。如果有任何提高性能的想法请分享。

foreach (var part in quoteParts)
{                            
    var presentPart = existingPart.FirstOrDefault(p => p.PartName == part.PartNumber);

    if (presentPart != null)
    {
        int partID = presentPart.ID;
        string partNumber = Convert.ToString(presentPart.PartName);

        foreach (var quotesPart in quoteStepInProcesses)
        {
            var presentStepInProcess = existingStepInProcesses.FirstOrDefault(p => p.ProcessId == quotesPart.StepInProcessID && quotesPart.PartNumber == partNumber); 

            if (presentStepInProcess != null)
            {
                PartProcesses.Add(new PartProcessDto
                {
                    ProcessName = Convert.ToString(presentStepInProcess.ID),
                    PartName = Convert.ToString(presentPart.ID)
                });
            }
        }
    }
}

1 个答案:

答案 0 :(得分:9)

您至少有两个地方在循环中使用FirstOrDefault来查找记录。我要尝试的第一件事就是预先索引数据;例如:

var partsByName = existingPart.ToDictionary(x => x.PartName);
foreach (var part in quoteParts)
{
    if(partsByName.TryGetValue(part.PartNumber, out var presentPart))
    {
        // ...
    }
}

existingStepInProcesses通过ProcessId类似。另请注意,最里面的FirstOrDefault&& quotesPart.PartNumber == partNumber)中的第二次测试实际上并未过滤p,因此应该从该查找移动远离。所以:在第一个ToDictionary旁边的第一个循环之外:

var processes = existingStepInProcesses.ToDictionary(x => x.ProcessId);

然后在最里面的循环中:

if (quotesPart.PartNumber == partNumber &&
    processes.TryGetValue(quotesPart.StepInProcessID, out var presentStepInProcess))
{
    // ...
}

可能也可以使用quoteStepInProcesses删除第二个foreach - 这取决于您期望的匹配数量。如果有多个:可能.ToLookup而不是ToDictionary