随着时间的推移,添加到List <t>会变得非常慢

The*_*Man 3 c# winforms

我正在解析一个大约有1000行的html表.我将~10个字符串从<td>每行中的一个添加到一个list<string>对象.前200个左右的循环非常快,但随着时间的推移变得越来越慢.

这是我正在使用的代码:

List<string> myList = new List<string>();
        int maxRows = numRows;


        for (int i = 1; i < maxRows; i++)
        { 
            TableRow newTable = myTable.TableRows[i];
            string coll = string.Format("{0},{1},{2},{3},{4}",newTable.TableCells[0].Text,newTable.TableCells[1].Text,newTable.TableCells[2].Text,newTable.TableCells[3].Text,newTable.TableCells[4].Text);
            myList.Add(coll);
            label1.Text = i.ToString();
        }
Run Code Online (Sandbox Code Playgroud)

我应该使用数组吗?

编辑:我将上面的代码放在一个新方法中,该方法使用以下代码在新的Thread标签控件上运行,然后更新我的标签控件:

label1.Invoke((MethodInvoker)delegate
                {
                    label1.Text = i.ToString();
                });
Run Code Online (Sandbox Code Playgroud)

程序以一致的速度运行,不会阻止UI.

San*_*ath 10

如果您大致知道集合中的范围(项目数),最好使用数组.

原因:如果列表已满,每次向List添加一个元素时,它会分配新的内存块以保存当前空间的两倍并复制其中的所有内容,然后继续附加其他条目,直到它变满,再添加一个分配副本周期.

以下是AFAIK的工作原理,默认情况下以16个元素开头,当你向列表中添加第17个元素时,它会分配32个元素,然后复制16个,然后继续17到32个并重复这个过程,因此速度较慢但提供了灵活性不必事先确定长度.这可能是你看到阻力的原因.

谢谢@Dyppl var list = new List<int>(1000);这也是一个优雅的选择,因为@Dyppl认为它是两个世界中最好的.

  • 除了内存分配非常快的事实。预设List &lt;&gt;可以有所帮助,但这大约是1000个字符串引用的列表。就我而言,Arrays与List &lt;&gt;倾向于将其视为微优化领域。 (2认同)

Tri*_*dad 9

我测试的字符串添加到列表中,并用它为基准LIST_SIZE百万(一百万)项和LIST_SIZE10万(一百千)项目.这样我们就可以比较它如何扩展.

我每次测试5次并平均运行时间.


var l = new List<string>();
for (var i = 0; i < LIST_SIZE; ++i) {
    l.Add("i = " + i.ToString());
}
Run Code Online (Sandbox Code Playgroud)

LIST_SIZE1000000需要1519毫秒

LIST_SIZE100000需要96毫秒


var l = new List<string>(LIST_SIZE);
for (var i = 0; i < LIST_SIZE; ++i) {
    l.Add("i = " + i.ToString());
}
Run Code Online (Sandbox Code Playgroud)

LIST_SIZE1000000需要1386毫秒

LIST_SIZE100000需要65毫秒


var l = new string[LIST_SIZE];
for (var i = 0; i < LIST_SIZE; ++i) {
    l[i] = "i = " + i.ToString();
}
Run Code Online (Sandbox Code Playgroud)

LIST_SIZE1000000需要1510毫秒

LIST_SIZE100000需要66毫秒

所以,我们可以注意到两件事:

  • 列表越大,添加每个项目确实需要更多时间
  • 在1000个项目列表中,差异不应该是明显的

那么我会得出结论,瓶颈是你调用的其他方法之一.

  • 这已经做了很多次.这是一篇不错的文章,附图:http://allantech.blogspot.com/2007/03/performance-arraylist-vs-list.html (2认同)