Introduction
Video games programmer have always the same objective : write fastest code as possible. There's no need to use assembly everywhere or know MSIL by heart, just use a profiler and see ;p Loop is something very usefull and very used in C# but what is the best solution for an ArrayList to browse all items ? Is IEnumerator faster than for () ? Bets are opened. For this article, I've chosen Red Gate Ants Profiler 2.6.0 Build 62 (http://www.red-gate.com/products/ants_profiler/index.htm). Results are... suprising.
ArrayList
I've found 4 ways to browse an ArrayList and Antony another one :
static public void Browse1 (ArrayList list)
{
int Total = 0;
for (int i = 0; i < list.Count; i++)
{
Total += (int)list[i];
}
}
static public void Browse2 (ArrayList list)
{
int Total = 0;
int Count = list.Count;
for (int i = 0; i < Count; i++)
{
Total += (int)list[i];
}
}
static public void Browse3 (ArrayList list)
{
int Total = 0;
IEnumerator Iterator = list.GetEnumerator ();
while (Iterator.MoveNext ())
{
Total += (int)Iterator.Current;
}
}
static public void Browse4 (ArrayList list)
{
int Total = 0;
foreach (int i in list)
{
Total += i;
}
}
static public void Browse5(ArrayList list)
{
int Total = 0;
for (int i = list.Count - 1; i >= 0; i--)
{
Total += (int)list[i];
}
}
In Main(), just fill the ArrayList :
ArrayList MyList = new ArrayList ();
DateTime CurrentTime = DateTime.Now;
Random rand = new Random (CurrentTime.Millisecond);
int Count = (int)(CurrentTime.Ticks % (1<<25));
int NewValue = (rand.Next () % 100);
Console.WriteLine ("Fill list with {0} elements", Count);
for (int i = 0; i < Count; i++)
{
MyList.Add (NewValue);
}
DateTime d1, d2, d3, d4, d5, d6;
d1 = DateTime.Now;
Console.WriteLine ("Browse1");
Browse1 (MyList);
d2 = DateTime.Now;
Console.WriteLine ("Browse2");
Browse2 (MyList);
d3 = DateTime.Now;
Console.WriteLine ("Browse3");
Browse3 (MyList);
d4 = DateTime.Now;
Console.WriteLine ("Browse4");
Browse4 (MyList);
d5 = DateTime.Now;
Console.WriteLine("Browse5");
Browse5(MyList);
d6 = DateTime.Now;
TimeSpan r1,r2,r3,r4,r5;
r1 = d2 - d1;
r2 = d3 - d2;
r3 = d4 - d3;
r4 = d5 - d4;
r5 = d6 - d5;
Console.WriteLine("Browse1 : {0}", r1.TotalMilliseconds);
Console.WriteLine("Browse2 : {0}", r2.TotalMilliseconds);
Console.WriteLine("Browse3 : {0}", r3.TotalMilliseconds);
Console.WriteLine("Browse4 : {0}", r4.TotalMilliseconds);
Console.WriteLine("Browse5 : {0}", r5.TotalMilliseconds);
Console.WriteLine("Press any key");
Console.ReadKey();
Here are the results (Release Version, PIV C, XP Pro SP2) :
Count |
24 145 243 |
18 491 373 |
Browse1 |
327.55 ms |
249.56 ms |
Browse2 |
233.96 ms |
202.77 ms |
Browse3 |
717.48 ms |
545.91 ms |
Browse4 |
717.48 ms |
561.51 ms |
Browse5 |
249.56 ms |
171.57 ms |
Something interesting is in first case, both, Solution 3 & 4 have the same time but not the second one.
Method 2 or 5 seems to be the fastest but not always in the same order.
We can do other tests on other computers:
- Retry with Red Gate Ants Profiler and not only on timer
- Look physical memory allocation to avoid hard disk swap
- Test on virtual machine