Reputation: 53223
Out of curiosity I wanted to test the number of ticks to compare a GenericList against an ArrayList.
And for the below code when I check the stopwatches, ArrayList seems to faster.
Do I make something wrong or is there an explanation for this? (I believed List sto be much faster)
Tesing Code and the output below:
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));
}
Upvotes: 7
Views: 407
Reputation: 108790
You did not eliminate first execution effects like JIT. Generics need to be compiled once for every value type argument.
ArrayList
is already precompiled with ngen.
List<T>
is only precompiled for certain parameter types(I read that the core libraries instantiate some of the most important generics for the common arguments, like object, bool, int,...), if at all. So it will incur a one time cost.
You should also note, that most of the performance cost of ArrayList
is indirect: The boxing puts higher pressure on the GC, and uses more memory. But your test won't measure that. The cost of producing more garbage also depends on how many other objects exist, and on the lifetime of the objects.
When you write tests, you should either execute all code once before the actual test, or use so many iterations that one time costs are negligible. It's also important to use a release build and run without the debugger attached.
Upvotes: 5
Reputation: 14786
Change your test program to run your method at least twice and ignore the first run. The results are caused by code generation and jitting for the concrete type List<Point>
.
On my machine this leads to the following output:
Watch 0 : 154
Watch 1 : 74
Watch 0 > Watch 1 : True
Which is pretty much what one would expect.
Upvotes: 7