Click here to Skip to main content
15,889,462 members
Articles / Programming Languages / Visual Basic
Article

FOREACH Vs. FOR (C#)

Rate me:
Please Sign up or sign in to vote.
3.50/5 (81 votes)
19 Apr 20044 min read 645.9K   55   75
Checking the performance between foreach and for loops in depth.

Introduction

In my experience, there are two kinds of programmers. Those who write something to get the work done and those who want to write good code. But, here we get a big question. What is good code? Good code comes from good programming practices. What are good programming practices? Actually, my aim here is not to talk about good programming practices (I’m planning to write something related to that in future!), rather to talk more about writing something which will be more effective. I'm only going to look more deeper of two loops which are commonly used nowadays, and their differences in the aspect of performance.

Background

Must be familiar with IL and assembly code. Also, better to have a good knowledge on how .NET framework works. Some knowledge of JIT is also needed to understand what is exactly happening.

Using the code

I’m going to take a very small piece of code for two popular looping statements for and foreach. We will look some code and will see what it does, more in detail about the functionality.

FOR

C#
int[] myInterger = new int[1];
int total = 0;
for(int i = 0; i < myInterger.Length; i++)
{
    total += myInterger[i];
}

foreach

C#
int[] myInterger = new int[1];
int total = 0;
foreach(int i in myInterger) 
{
    total += i;
}

Both codes will produce the same result. foreach is used on top of collections to traverse through while for can be used on anything for the same purpose. I’m not going to explain whatsoever about the code. Before going in more deeper, I think all of you are familiar with ILDasm which is used to generate IL code, and CorDbg tool which is normally used to generate JIT compiled code.

The IL code produced by C# compiler is optimized up to certain extend, while leaving some part to JIT. Anyway, this is not really what matters to us. So, when we talk about the optimization, two things we must consider. First is C# compiler and the second is JIT.

So, rather than looking more deep into IL code, we will see more about the code which is emitted by JIT. That is the code which will run on our machine. I’m now using AMD Athlon 1900+. The code highly depends on our hardware. Therefore, what you may get from your machine may differ from mine up to a certain extend. Anyway, the algorithms wont change that much.

In variable declaration, foreach has five variable declarations (three Int32 integers and two arrays of Int32) while for has only three (two Int32 integers and one Int32 array). When it goes to loop through, foreach copies the current array to a new one for the operation. While for doesn't care of that part.

Here, I’m going into the exact difference between the codes.

FOR

Instruction                           Effect
ASM
cmp     dword ptr [eax+4],0           i<myInterger.Length
jle     0000000F
mov     ecx,dword ptr [eax+edx*4+8]   total += myInterger[i]
inc     edx                           ++i
cmp     esi,dword ptr [eax+4]         i<myInterger.Length
jl      FFFFFFF8

I’ll explain what is happening here. The esi register which holds the value of i and the length of myInteger array are compared at two stages. The first one is done only once to check the condition and if the loop can continue, the value is added. For the loop, it is done at the second stage. Inside the loop, it is well optimized and as explained, the work is done with perfect optimization.

foreach

Instruction                            Effect
ASM
cmp     esi,dword ptr [ebx+4]          i<myInterger.Length
jl      FFFFFFE3
cmp     esi,dword ptr [ebx+4]          i<myInterger.Length 
jb      00000009
mov     eax,dword ptr [ebx+esi*4+8] 
mov     dword ptr [ebp-0Ch],eax  
mov     eax,dword ptr [ebp-0Ch]
add     dword ptr [ebp-8],eax          total += i
inc     esi                            ++i
cmp     esi,dword ptr [ebx+4]          i<myInterger.Length
jl      FFFFFFE3

Anyone will say that both are not the same. But we will look why it differs from the for loop. The main reason for the difference is that both of them are differently understood by the compiler. The algorithm they are using is different. Two compare statements one after the other is unnecessary. It is doing the same thing again and again for no reason!

ASM
cmp                    esi,dword ptr [ebx+4]   
jl                         FFFFFFE3
cmp                    esi,dword ptr [ebx+4]

It also uses some unnecessary move statements which also may (not always, but depends) reduce the performance of the code. foreach is thinking everything as a collection and treating them as a collection. I feel, that will also reduce the performance of the work.

Therefore, I strongly feel if you are planning to write high performance code that is not for collections, use for loop. Even for collections, foreach may look handy when using, but it's not that efficient. Therefore, I strongly recommend everyone to use for loop rather than foreach at any stage.

Points of Interest

Actually, I did a small research on the performance issue of codes mainly on .NET languages. While I was testing, I found that it was really a must to know how JIT works and to debug the code generated by JIT compiler. It took some time to understand the code.

History

This is submitted on 19th of April 2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Singapore Singapore
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
VMAtm2-Oct-17 12:08
VMAtm2-Oct-17 12:08 
GeneralWhich is faster depends on what you're iterating over. Pin
Member 1024450319-May-16 20:36
Member 1024450319-May-16 20:36 
GeneralMy vote of 1 Pin
Member 97054859-Oct-14 21:07
Member 97054859-Oct-14 21:07 
QuestionHelpful Pin
umd198911-Feb-14 23:25
umd198911-Feb-14 23:25 
GeneralMy vote of 1 Pin
VMAtm24-Sep-13 21:52
VMAtm24-Sep-13 21:52 
Suggestionforeach loop is better than for loop Pin
abiruban16-Mar-13 21:33
abiruban16-Mar-13 21:33 
GeneralRe: foreach loop is better than for loop Pin
rahulsundar29-Jun-14 17:50
rahulsundar29-Jun-14 17:50 
GeneralMy vote of 1 Pin
Kamyar29-Jan-13 5:23
Kamyar29-Jan-13 5:23 
GeneralFor Vs Foreach - Benchmark 2013 Pin
adriancs21-Jan-13 19:21
mvaadriancs21-Jan-13 19:21 
GeneralMy vote of 1 Pin
RutgerStorm10-Jan-13 0:23
RutgerStorm10-Jan-13 0:23 
GeneralMy vote of 1 Pin
Snorri Kristjansson9-Jan-13 2:30
professionalSnorri Kristjansson9-Jan-13 2:30 
QuestionBetter to avoid using ForEach statements Pin
aripaka14-Oct-12 20:27
aripaka14-Oct-12 20:27 
GeneralMy vote of 5 Pin
kevinprasannan6-Jul-12 23:50
kevinprasannan6-Jul-12 23:50 
QuestionListen to the man Pin
msdevtech2-Jul-12 2:16
msdevtech2-Jul-12 2:16 
AnswerRe: Listen to the man Pin
RutgerStorm10-Jan-13 0:07
RutgerStorm10-Jan-13 0:07 
GeneralMy vote of 5 Pin
Member 85055188-Feb-12 18:13
Member 85055188-Feb-12 18:13 
QuestionAlternatives to Looping Pin
malcolmvr15-Dec-11 7:14
malcolmvr15-Dec-11 7:14 
GeneralMy vote of 1 Pin
akjoshi11-Dec-11 23:59
akjoshi11-Dec-11 23:59 
Answer[My vote of 1] ForEach is for Objects [modified] Pin
sekhar Aripaka3-May-11 17:40
sekhar Aripaka3-May-11 17:40 
GeneralMy vote of 1 Pin
Stein Gregory24-Apr-11 22:05
Stein Gregory24-Apr-11 22:05 
GeneralFOREACH vs FOR, tested again. FOR wins. Pin
bluedog says3-Jun-09 10:44
bluedog says3-Jun-09 10:44 
While reading all the conflicting reports, I wrote my own little sample, posted below. Here are the results:

Object Test Results

FOR loop time on ArrayList with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 88.6

FOREACH loop time on ArrayList with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 115.9

FOR loop time on generic collection with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 84.4

FOREACH loop time on generic collection with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 87.1

FOR loop time on array with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 48.1

FOREACH loop time on array with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 49.8

Int Test Results

FOR loop time on ArrayList with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 65.1

FOREACH loop time on ArrayList with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 134

FOR loop time on generic collection with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 51.6

FOREACH loop time on generic collection with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 72.2

FOR loop time on array with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 17.5

FOREACH loop time on array with 2147483 items looped 10 times:
Average Elapsed Milliseconds: 21.7

This tests ArrayLists, Generic collections, and arrays holding the same type of information with the same lengths. The for/foreach loops do nothing more then set a number. Personally I wish the results were the opposite as foreach is less to type then for (int i = i < ? ; i++)

You can run this sample and it will loop millions and millions of objects/ints and average them to produce a viable result. I ran it about 10 times now illiterating through over 100 million items with the same results each time.

By default the sample will pause 5 seconds in between runs. You can optionally output the results to a file as well. If you find any issues please post them. FYI this sample was ran on a 1.6ghz x 2 Vista laptop with 2gb of ram if you want to compare results.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Collections;
using System.Threading;
using System.IO;

namespace FOREACHVSFOR
{
    /// <summary>
    /// Checks FOREACH VS FOR.
    /// Code can be ran to check multiple times and take the average or to take the total.
    /// </summary>
    class Program
    {
        #region Array/Collection
        static ArrayList ari1 = null;
        static ArrayList ari2 = null;
        static List<int> ari3 = null;
        static List<int> ari4 = null;
        static int[] ari5 = null;
        static int[] ari6 = null;

        static ArrayList arl1 = null;
        static ArrayList arl2 = null;
        static List<BoringObjectClass> arl3 = null;
        static List<BoringObjectClass> arl4 = null;
        static BoringObjectClass[] arl5 = null;
        static BoringObjectClass[] arl6 = null;
        #endregion

        #region Times
        static long ar1Time = 0;
        static long ar2Time = 0;
        static long ar3Time = 0;
        static long ar4Time = 0;
        static long ar5Time = 0;
        static long ar6Time = 0;
        #endregion

        /// <summary>
        /// Class to test out in collection.
        /// </summary>
        class BoringObjectClass: Object
        {
            /// <summary>
            /// Some int to use.
            /// </summary>
            public int SomeInt = 0;
            public BoringObjectClass(int v)
            {
                SomeInt=v;
            }
        }
        /// <summary>
        /// Set at runtime by user.
        /// </summary>
        static int intsToTest = 0;

        /// <summary>
        /// Set at runtime by user.
        /// </summary>
        static int objectsToTest = 0;

        /// <summary>
        /// Output results to a log file?
        /// </summary>
        static bool SaveToLog = true;

        /// <summary>
        /// Log file name, if you want to log info set SaveToLog to true.
        /// </summary>
        static string LogFileName = "FORVSFOREACH.log";

        /// <summary>
        /// Set to true if you want to append the current log file (if any) otherwise we will overwrite.
        /// </summary>
        static bool AppendLog = false;

        /// <summary>
        /// Let the thread sleep in between runs.
        /// </summary>
        static int SleepTimeInBetween = 5000;

        /// <summary>
        /// Stores results.
        /// </summary>
        static StringBuilder builder;

        /// <summary>
        /// Char array to split new lines.
        /// </summary>
        static char[] sp = new char[] { char.Parse("\n") };

        /// <summary>
        /// Runs the check on arrays of ints.
        /// </summary>
        static void IntCheck()
        {
            Stopwatch sp = new Stopwatch();
            int fill = 0;

            if (ari1 == null || ari1.Count != intsToTest)
            {
                ari1 = null;
                ari1 = new ArrayList(intsToTest);
            }
            if (ari2 == null || ari2.Count != intsToTest)
            {
                ari2 = null;
                ari2 = new ArrayList(intsToTest);
            }
            if (ari3 == null || ari3.Count != intsToTest)
            {
                ari3 = null;
                ari3 = new List<int>(intsToTest);
            }
            if (ari4 == null || ari4.Count != intsToTest)
            {
                ari4 = null;
                ari4 = new List<int>(intsToTest);
            }
            if (ari5 == null || ari5.Length != intsToTest)
            {
                ari5 = null;
                ari5 = new int[intsToTest];
            }
            if (ari6 == null || ari6.Length != intsToTest)
            {
                ari6 = null;
                ari6 = new int[intsToTest];
            }

            while (fill < intsToTest)
            {
                ari1.Add(fill);
                ari2.Add(fill);
                ari3.Add(fill);
                ari4.Add(fill);
                ari5[fill] = fill;
                ari6[fill] = fill;

                fill++;
            }

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < ari1.Count; i++)
                fill = (int) ari1[i];
            sp.Stop();
            ar1Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (int i in ari2)
                fill = (int) ari2[i];
            sp.Stop();
            ar2Time+= sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < ari3.Count; i++)
                fill = ari3[i];
            sp.Stop();
            ar3Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (int i in ari4)
                fill = ari4[i];
            sp.Stop();
            ar4Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < ari5.Length; i++)
                fill = ari5[i];
            sp.Stop();
            ar5Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (int i in ari6)
                fill = ari6[i];
            sp.Stop();
            ar6Time += sp.ElapsedMilliseconds;
            fill = 0;
        }

        /// <summary>
        /// Runs the check on arrays of objects.
        /// </summary>
        static void ObjectCheck()
        {
            Stopwatch sp = new Stopwatch();
            int fill = 0;

            if (arl1 == null || arl1.Count != objectsToTest)
            {
                arl1 = null;
                arl1 = new ArrayList(objectsToTest);
            }
            if (arl2 == null || arl2.Count != objectsToTest)
            {
                arl2 = null;
                arl2 = new ArrayList(objectsToTest);
            }
            if (arl3 == null || arl3.Count != objectsToTest)
            {
                arl3 = null;
                arl3 = new List<BoringObjectClass>(objectsToTest);
            }
            if (arl4 == null || arl4.Count != objectsToTest)
            {
                arl4 = null;
                arl4 = new List<BoringObjectClass>(objectsToTest);
            }
            if (arl5 == null || arl5.Length != objectsToTest)
            {
                arl5 = null;
                arl5 = new BoringObjectClass[objectsToTest];
            }
            if (arl6 == null || arl6.Length != objectsToTest)
            {
                arl6 = null;
                arl6 = new BoringObjectClass[objectsToTest];
            }

            while (fill < objectsToTest)
            {
                arl1.Add(new BoringObjectClass(fill));
                arl2.Add(new BoringObjectClass(fill));
                arl3.Add(new BoringObjectClass(fill));
                arl4.Add(new BoringObjectClass(fill));
                arl5[fill] = new BoringObjectClass(fill);
                arl6[fill] = new BoringObjectClass(fill);

                fill++;
            }

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < arl1.Count; i++)
                fill = (arl1[i] as BoringObjectClass).SomeInt;
            sp.Stop();
            ar1Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (BoringObjectClass i in arl2)
                fill = i.SomeInt;
            sp.Stop();
            ar2Time+= sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < arl3.Count; i++)
                fill = arl3[i].SomeInt;
            sp.Stop();
            ar3Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (BoringObjectClass i in arl4)
                fill = i.SomeInt;
            sp.Stop();
            ar4Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            for (int i = 0; i < arl5.Length; i++)
                fill = arl5[i].SomeInt;
            sp.Stop();
            ar5Time += sp.ElapsedMilliseconds;

            fill = 0;
            sp.Reset();
            Thread.Sleep(SleepTimeInBetween);
            sp.Start();
            foreach (BoringObjectClass i in arl6)
                fill = i.SomeInt;
            sp.Stop();
            ar6Time += sp.ElapsedMilliseconds;
            fill = 0;
        }

        /// <summary>
        /// Starts the check on arrays of ints.
        /// </summary>
        static void BeginIntCheck()
        {
            int illiterations = 0;

            while (true)
            {
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("Integer Test.");
                Console.WriteLine("Press: Enter to run [n] times. R to average [n] times. A to add [n] times. Escape to go back.");
               
                ar1Time = 0;
                ar2Time = 0;
                ar3Time = 0;
                ar4Time = 0;
                ar5Time = 0;
                ar6Time = 0;
                builder = new StringBuilder();

                switch (Console.ReadKey().Key)
                {
                    case ConsoleKey.Enter:
                        intsToTest = GetCount();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        IntCheck();

                        builder.AppendLine("Int Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar1Time);
                        builder.AppendLine("FOREACH loop time on ArrayList with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar2Time);
                        builder.AppendLine("FOR loop time on generic collection with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar3Time);
                        builder.AppendLine("FOREACH loop time on generic collection with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar4Time);
                        builder.AppendLine("FOR loop time on array with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar5Time);
                        builder.AppendLine("FOREACH loop time on array with " + intsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar6Time);
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.A:
                        intsToTest = GetCount();
                        Console.WriteLine();
                        illiterations = GetIlliterations();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        for (int i = 0; i < illiterations; i++)
                            IntCheck();

                        builder.AppendLine("Int Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar1Time);
                        builder.AppendLine("FOREACH loop time on ArrayList with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar2Time);
                        builder.AppendLine("FOR loop time on generic collection with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar3Time);
                        builder.AppendLine("FOREACH loop time on generic collection with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar4Time);
                        builder.AppendLine("FOR loop time on array with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar5Time);
                        builder.AppendLine("FOREACH loop time on array with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar6Time);
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.R:
                        intsToTest = GetCount();
                        Console.WriteLine();
                        illiterations = GetIlliterations();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        for (int i = 0; i < illiterations; i++)
                            IntCheck();

                        builder.AppendLine("Int Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar1Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on ArrayList with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar2Time / (decimal) illiterations ));
                        builder.AppendLine("FOR loop time on generic collection with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar3Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on generic collection with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar4Time /(decimal) illiterations ));
                        builder.AppendLine("FOR loop time on array with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar5Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on array with " + intsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar6Time / (decimal) illiterations ));
                        builder.AppendLine();
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.Escape:
                        return;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// Starts the check on arrays of objects.
        /// </summary>
        static void BeginObjCheck()
        {
            int illiterations = 0;

            while (true)
            {
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("Object Test.");
                Console.WriteLine("Press: Enter to run [n] times. R to average [n] times. A to add [n] times. Escape to go back.");

                ar1Time = 0;
                ar2Time = 0;
                ar3Time = 0;
                ar4Time = 0;
                ar5Time = 0;
                ar6Time = 0;
                builder = new StringBuilder();

                switch (Console.ReadKey().Key)
                {
                    case ConsoleKey.Enter:
                        objectsToTest = GetCount();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        ObjectCheck();

                        builder.AppendLine("Object Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar1Time);
                        builder.AppendLine("FOREACH loop time on ArrayList with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar2Time);
                        builder.AppendLine("FOR loop time on generic collection with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar3Time);
                        builder.AppendLine("FOREACH loop time on generic collection with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar4Time);
                        builder.AppendLine("FOR loop time on array with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar5Time);
                        builder.AppendLine("FOREACH loop time on array with " + objectsToTest + " items:");
                        builder.AppendLine("Elapsed Milliseconds: " + ar6Time);
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.A:
                        objectsToTest = GetCount();
                        Console.WriteLine();
                        illiterations = GetIlliterations();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        for (int i = 0; i < illiterations; i++)
                            ObjectCheck();

                        builder.AppendLine("Object Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar1Time);
                        builder.AppendLine("FOREACH loop time on ArrayList with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar2Time);
                        builder.AppendLine("FOR loop time on generic collection with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar3Time);
                        builder.AppendLine("FOREACH loop time on generic collection with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar4Time);
                        builder.AppendLine("FOR loop time on array with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar5Time);
                        builder.AppendLine("FOREACH loop time on array with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Total Elapsed Milliseconds: " + ar6Time);
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.R:
                        objectsToTest = GetCount();
                        Console.WriteLine();
                        illiterations = GetIlliterations();
                        Console.WriteLine();
                        Console.WriteLine("Running... This may take a few minutes.");

                        for (int i = 0; i < illiterations; i++)
                            ObjectCheck();

                        builder.AppendLine("Object Test Results");
                        builder.AppendLine("FOR loop time on ArrayList with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar1Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on ArrayList with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar2Time / (decimal) illiterations ));
                        builder.AppendLine("FOR loop time on generic collection with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar3Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on generic collection with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar4Time /(decimal) illiterations ));
                        builder.AppendLine("FOR loop time on array with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar5Time / (decimal) illiterations ));
                        builder.AppendLine("FOREACH loop time on array with " + objectsToTest + " items looped " + illiterations + " times:");
                        builder.AppendLine("Average Elapsed Milliseconds: " + ( ar6Time / (decimal) illiterations ));
                        builder.AppendLine();
                        LogIt();

                        builder.Remove(0, builder.Length);
                        builder = null;

                        break;
                    case ConsoleKey.Escape:
                        return;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// Gets the count of elements to use for testing. Too high and your memory will pass 1gb.
        /// </summary>
        /// <returns>Int containing count.</returns>
        static int GetCount()
        {
            while (true)
            {
                Console.WriteLine();
                Console.WriteLine("How many elements to check?");
                Console.WriteLine("Enter 0 to use the default of int.MaxValue / 1000.");

                int iElements = 0;
                if (int.TryParse(Console.ReadLine(), out iElements))
                {
                    if (iElements > 0)
                        return iElements;
                    else if (iElements == 0)
                        return int.MaxValue / 1000;
                }
            }
        }

        /// <summary>
        /// How many times to run the test?
        /// </summary>
        /// <returns>Int holding requested illiterations.</returns>
        static int GetIlliterations()
        {
            while (true)
            {
                Console.WriteLine();
                Console.WriteLine("How many illiterations?");

                int iIlliterations = 0;
                if (int.TryParse(Console.ReadLine(), out iIlliterations))
                {
                    if (iIlliterations > 0)
                        return iIlliterations;
                }
            }
        }

        /// <summary>
        /// Log to file if SaveToLog is true. Print results out to the console.
        /// </summary>
        static void LogIt()
        {
            if (SaveToLog && builder.Length > 0)
            {
                StreamWriter wrt = null;

                try
                {
                    wrt = new StreamWriter(LogFileName, AppendLog);

                    foreach (string L in builder.ToString().Split(sp))
                        if (L.Length > 0)
                        {
                            Console.WriteLine(L);
                            wrt.WriteLine(L);
                        }
                }
                finally
                {
                    if (wrt != null)
                    {
                        wrt.Close();
                        wrt = null;
                    }
                }
            }
            else
                foreach (string L in builder.ToString().Split(sp))
                    if (L.Length > 0)
                        Console.WriteLine(L);
        }

        /// <summary>
        /// FOREACH VS FOR CHECK
        /// </summary>
        /// <param name="args">Nothing</param>
        static void Main(string[] args)
        {
            Console.WriteLine("FOREACH VS FOR CHECK");

            while (true)
            {
                Console.WriteLine();
                Console.WriteLine("Press: O to test with objects. I to test with integers. Escape to exit.");

                switch (Console.ReadKey().Key)
                {
                    case ConsoleKey.O:
                        BeginObjCheck();
                        break;
                    case ConsoleKey.I:
                        BeginIntCheck();
                        break;
                    case ConsoleKey.Escape:
                        return;
                }
            }

        }
    }
}

GeneralRe: FOREACH vs FOR, tested again. FOR wins. Pin
adriancs22-Jan-13 20:57
mvaadriancs22-Jan-13 20:57 
GeneralMy vote of 1 Pin
iosgmbh14-Apr-09 20:52
iosgmbh14-Apr-09 20:52 
Generallink to a correct article Pin
korsuas16-May-08 0:15
korsuas16-May-08 0:15 
Generalforeach copies the current array to a new one Pin
PIEBALDconsult15-May-08 9:43
mvePIEBALDconsult15-May-08 9:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.