【问题标题】:How to increase performance of foreach loop如何提高 foreach 循环的性能
【发布时间】:2015-05-14 12:32:46
【问题描述】:

我正在使用 foreach 循环来计算问题的答案。

它会针对一个问题计算所有答案,但是当它加载下一个问题时,每次都需要一分钟。我怎样才能减少这个时间?

List<Questionnaire> myQuestionnaires = report.Project
                                             .Questionnaires
                                             .Where(q => q.Active)
                                             .ToList<Questionnaire>();          

foreach (Questionnaire q in myQuestionnaires)
{
    foreach (ItemAnswer a in q.Answers)
    {
        //possible answers 
    }
}                

【问题讨论】:

  • 这里的 for-each 循环正在处理内存中的集合,所以它应该很快!当您调用 .ToList() 方法时,您确定延迟不是在获取问题吗?你的数据存储是什么?你得到了多少结果?
  • 这里根本不需要.ToList,它会让你对集合进行两次迭代。只需将顶部的 List&lt;Questionaire&gt; 替换为 var 并删除末尾的 ToList
  • 数据存储在 MySQL 上,结果超过 200 个问题
  • 您能提供找到可能答案的条件吗?
  • 几百条记录是一个小集合。即使您每次都获取所有 regords 并循环它们,这仍然只需要几分之一秒。如果需要将近一分钟的时间,则说明您无法通过更改代码来解决问题。

标签: c# asp.net-mvc-3 loops foreach


【解决方案1】:

我不会使用 .ToList() 或 .AsEnumerable()。这两个函数将执行您的 linq 语句生成的 T-SQL 并将所有记录拉入内存。

更好的选择是继续使用 linq 通过谓词过滤结果。

var query = report.Project
                  .Questionnaires
                  .Where(q => q.Active && q.Answers == /*some condition*/)

var query = report.Project
                  .Questionnaires
                  .Where(q => q.Active)
                  .Select(q => q.Answers) // Select the answers only
                  .Where(answers => answers.Property == /* some condition */)

然后,在您完成过滤记录后,在读取时调用 .ToList() 或 .AsEnumerable() 以获取结果。

这使您可以使用数据库完成所有工作,而不是将集合拉入内存并进行迭代。

【讨论】:

    【解决方案2】:

    似乎是延迟加载的问题,因为LINQ默认启用了延迟加载。在您的代码部分中,它将为每个问题从 db 加载所有答案(没有任何连接)。

    您可以通过使用控制数据上下文级别的延迟加载

        report.DeferredLoadingEnabled=false;
    

    现在您必须编写一些额外的代码行来获取答案,因为现在“q.Answers”将没有数据。您可以编写另一个 Linq 来在第一个 foreach 循环中获取答案,但它不会花那么多时间。

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 1970-01-01
      • 2023-03-09
      • 2021-06-19
      • 1970-01-01
      • 2020-08-25
      • 2021-07-04
      • 2019-10-29
      • 2013-08-14
      相关资源
      最近更新 更多