有没有更有效的方式编写此循环?

问题描述

我有以下循环很长的循环,queryResult有397464行,每行有15列,因此迭代数将为397464 * 15 = 5961960 +外循环(397464) = 6359424次迭代。

问题是这导致页面超时花费了很长时间。 可以用更有效的方式写吗?

var rowHtml = String.Empty;

foreach (DaTarow row in queryResult.Rows)
{
    rowHtml += "<tr>";
    for (int i = 0; i < queryResult.Columns.Count; i++)
    {
        rowHtml += $"<td>{row[i]}</td>";
    }
    rowHtml += "</tr>";
}

解决方法

构建字符串:考虑使用StringBuilder。每次使用+运算符连接字符串时,都会在堆上创建一个新字符串。这适合个人使用,但是在像您这样的大型工作负载中,这可能会大大减慢速度。您可以在构造函数中指定StringBuilder的最大容量和启动容量,从而可以更好地控制应用程序的内存使用情况。

并行化:我不知道您应用的确切上下文,但是我建议看看System.Threading.Parallel类。它的For / Foreach方法允许您使用线程池对集合进行迭代,将线程转移到多个内核可以大大加快处理速度。

但是要小心:如果元素的顺序相关,则应将工作负载分成包,并为每个包构建子字符串。

编辑:更正:字符串连接只能在少数情况下才能真正并行化,在这种情况下,循环产生的每个子字符串的确切长度是固定的并且是已知的。在这种特殊情况下,可以将结果直接写入大型的预分配目标缓冲区。当使用char数组或指针时,这是完全可行的,但不建议与常规C#字符串或StringBuilders一起使用。

异步处理:看来您正在编写某种Web应用程序或服务器后端。如果您的内容是按需提供的,并且不需要在页面加载的确切时刻准备就绪,请考虑在页面等待服务器发送邮件的同时显示加载栏或一些“请稍候”行的通知。完成处理结果。

编辑:如注释中所建议,与从表中构造HTML字符串相比,有更好的方法来解决此问题。考虑使用那些替代某些复杂的内容加载方案。