在进行性能测试时,我发现了一些有趣的东西。
我注意到第一次插入LinkedList(C#Generics)的速度比列表头部的任何其他插入速度慢得多。我只是使用C#模板LinkedList,并使用AddFirst()每次插入LinkedList。为什么第一次插入最慢?
前五个插入结果:
首次插入列表:0.0152毫秒
第二次插入列表(头部):0.0006毫秒
第三次插入列表(头部):0.0003毫秒
第四次插入列表(头部):0.0006毫秒
第五次插入列表(头部):0.0006毫秒
性能测试代码:
using (StreamReader readText = new StreamReader("MillionNumbers.txt"))
{
String line;
Int32 counter = 0;
while ((line = readText.ReadLine()) != null)
{
watchTime.Start();
theList.AddFirst(line);
watchTime.Stop();
Double time = watchTime.Elapsed.TotalMilliseconds;
totalTime = totalTime + time;
Console.WriteLine(time);
watchTime.Reset();
++counter;
}
Console.WriteLine(totalTime);
Console.WriteLine(counter);
Console.WriteLine(totalTime / counter);
}
答案 0 :(得分:3)
单次手术的时机非常危险 - 最轻微的口吃会对结果产生巨大影响。此外,在此代码之前,您已经使用LinkedList<T>
完成了任何,这并不清楚,这意味着您需要计算AddFirst
的JIT,甚至可能涉及其他所有类型的JIT
定时只是第一次插入是相当困难的,因为一旦你完成它,你就不能轻易重复它。但是,您可以反复“插入和删除”时间,如下代码所示:
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
public static void Main(string[] args)
{
// Make sure we've JITted the LinkedList code
new LinkedList<string>().AddFirst("ignored");
LinkedList<string> list = new LinkedList<string>();
TimeInsert(list);
list.AddFirst("x");
TimeInsert(list);
list.AddFirst("x");
TimeInsert(list);
list.AddFirst("x");
}
const int Iterations = 100000000;
static void TimeInsert(LinkedList<string> list)
{
GC.Collect();
GC.WaitForPendingFinalizers();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < Iterations; i++)
{
list.AddFirst("item");
list.RemoveFirst();
}
sw.Stop();
Console.WriteLine("Initial size: {0}; Ticks: {1}",
list.Count, sw.ElapsedTicks);
}
}
我的结果:
Initial size: 0; Ticks: 5589583
Initial size: 1; Ticks: 8137963
Initial size: 2; Ticks: 8399579
这是我所期望的,因为根据内部表示,在添加和删除已填充的列表时,在连接“前一个头”方面要做的工作要多得多。
我的猜测是你正在看JIT时间,但实际上你的代码并没有真正准确到足够有用的时间,IMO。