1

我想对 ArrayList(System.Collections - C#) 在开头插入项目的速度进行性能测试。

我打开了一个文件来读取数据行,设置了一个秒表,还创建了一个 ArrayList 来添加项目(如下):

Stopwatch watchTime = new Stopwatch();
Double totalTime = 0; 
using (StreamReader readText = new StreamReader("data.txt"))
{
    String line;
    Int32 counter = 0; 
    while ((line = readText.ReadLine()) != null)
    {
    }
}

我使用计数器来跟踪我进入 ArrayList 的项目数量。

在while循环中,我有以下内容:

watchTime.Start();
theList.Insert(0, line);
watchTime.Stop();
Double time = watchTime.Elapsed.TotalMilliseconds;
totalTime = totalTime + time; 
Console.WriteLine(time);
watchTime.Reset();
++counter; 

这是检查将项目插入到 ArrayList 开头的速度的正确方法吗?

我制作了另一个程序,它做同样的事情 - 但是使用字典。令我惊讶的是,这个 ArrayList 插入项目所需的时间比 Dictionary 所需的时间长得多。为什么会这样?

4

2 回答 2

4

好吧,我建议:

  • 不要使用文件来获取输入。为什么要在系统中引入 IO?
  • 无需重复停止和启动秒表,只需在其中插入大量行ArrayList而不做任何其他事情。一口气计时那个大循环。

至于为什么Dictionary<,>更便宜 - 你没有显示任何代码,但基本上你的插入代码必须ArrayList在每次插入时复制整个内容。ArrayList维护一个数组来保存列表的内容。通常数组比列表大 - 当你在最后添加一个元素时,如果可以将新值分配到数组的正确位。如果将其插入其他位置,它必须复制数组元素以为新元素“腾出空间”。

你会发现最后添加它要快得多。Dictionary<,>使用完全不同的数据结构;它必须在某些时候调整大小,但通常会有非常不同的特征。

(我建议您使用List<T>而不是ArrayList开始,如果您想要一个可以在开头重复插入的集合,请考虑一个LinkedList<T>- 或者可能是一个队列或堆栈,具体取决于您以后要使用它做什么。)

于 2011-10-23T07:05:32.337 回答
1

太复杂了。在末尾附加的列表中“正常”读取文件,然后将第一个列表添加到第二个列表中进行基准测试。否则,您会尝试对太多的小动作进行基准测试,并且会遇到精度问题。

一些代码

ArrayList tempList = new ArrayList();

using (StreamReader readText = new StreamReader("data.txt"))
{
    String line;
    Int32 counter = 0; 
    while ((line = readText.ReadLine()) != null)
    {
        tempList.Add(line);
    }
}

ArrayList theList = new ArrayList();

Stopwatch watchTime = Stopwatch.StartNew();

foreach (string line in tempList)
{
    theList.Insert(0, line);
}

watchTime.Stop();

我会和Stopwatch你一起添加StartStop然后再添加Start一次,它将继续保持时间。要重置它,还有另一种方法,Restart.

正如其他人可能建议的那样:

  • 使用List<string>代替ArrayList(速度相同,但List<string>类型安全)
  • 一般来说,如果您只需要在列表的头部插入元素,则将它们插入尾部(更快)并“反转”索引(因此 index0是 index Count - 1, 1 是Count - 2等等)。列表不是为“中间”或“顶部”插入而“制作”的。它们是为“添加最后”而制作的。
于 2011-10-23T07:07:24.577 回答