pen*_*ake 7 .net c# generics clr arraylist
出于好奇,我想测试将GenericList与ArrayList进行比较的刻度数.
对于下面的代码,当我检查秒表时,ArrayList似乎更快.
我做错了还是有解释?(我相信List会更快)
测试代码和输出如下:
private static void ArrayListVsGenericList()
{
// Measure for ArrayList
Stopwatch w0 = new Stopwatch();
w0.Start();
ArrayList aList = new ArrayList();
for (int i = 0; i < 1001; i++)
{
Point p = new Point();
p.X = p.Y = i;
aList.Add(p);
}
foreach (Point point in aList)
{
int v0 = ((Point) aList[8]).X; //unboxing
}
w0.Stop();
// Measure for Generic List<Point>
Stopwatch w1 = new Stopwatch();
w1.Start();
List<Point> list = new List<Point>();
for (int i = 0; i < 1001; i++)
{
Point p = new Point();
p.X = p.Y = i;
list.Add(p);
}
foreach (var point in list)
{
int v1 = list[8].X;
}
w1.Stop();
Console.WriteLine("Watch 0 : " + w0.ElapsedTicks);
Console.WriteLine("Watch 1 : " + w1.ElapsedTicks);
Console.WriteLine("Watch 0 > Watch 1 : " + (w0.ElapsedTicks > w1.ElapsedTicks));
}
Run Code Online (Sandbox Code Playgroud)

更改测试程序以至少运行两次方法并忽略第一次运行.结果是由具体类型的代码生成和jitting引起的List<Point>.
在我的机器上,这导致以下输出:
Watch 0 : 154
Watch 1 : 74
Watch 0 > Watch 1 : True
Run Code Online (Sandbox Code Playgroud)
这几乎是人们所期望的.
你没有消除像JIT这样的第一个执行效果.需要为每个值类型参数编译一次泛型.
ArrayList 已经预编译了ngen.
List<T>仅针对某些参数类型进行了预编译(我读过核心库实例化了常见参数的一些最重要的泛型,如object,bool,int,...),如果有的话.所以它会产生一次性费用.
您还应该注意,大多数性能成本ArrayList是间接的:拳击对GC施加更高的压力,并使用更多的内存.但是你的测试不会衡量.产生更多垃圾的成本还取决于存在多少其他对象以及对象的生命周期.
在编写测试时,您应该在实际测试之前执行一次所有代码,或者使用那么多次迭代,一次成本可以忽略不计.使用发布版本并在没有附加调试器的情况下运行也很重要.