[C #] I tried to verify the speed of the loop statement

3 minute read

Recently, I’ve been writing more and more Windows Forms applications in C #. I think that the loop statement is basically the right person in the right place, but I mainly used the foreach statement (I like it because it is simple to write). There are various ways to write loop statements, but I was wondering what the speed is actually, so I summarized the verification results.

Loop statement type

for

for (Initialization formula;Conditional expression;Renewal formula) {
Iterative processing;
}

foreach

foreach (Variable name in array) {
Iterative processing;
}

while

while (Conditional expression) {
Iterative processing;
}

do-while

do {
Iterative processing;
} while (Conditional expression);

LINQ
Check the source for how to write

Validation source

Measure the average value of 100 times the function to find the sum of arrays with 100 million elements.

using System;
using System.Linq;

namespace Verify
{
    class Program
    {
        private static DateTime start;
        private static DateTime end;
        private static readonly int listCnt = 100000000;
        private static readonly int loopCnt = 100;
        private static readonly String resultFormat = "{0:0.0 ms}";

        /// <summary>
        ///Verification
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            LoopVerify();
        }

        /// <summary>
        ///Speed verification of loop functions
        ///  1.for statement
        ///  2.foreach statement
        ///  3.while statement
        ///  4. do-while statement
        ///  5.LINQ statement
        ///  6.LINQ statement (Pattern 2)
        ///Verify the speed at which the total elements of the array prepared in advance are calculated.
        /// </summary>
        private static void LoopVerify()
        {
            double[] doForVerifyList = new double[loopCnt];
            double[] doForEachVerifyList = new double[loopCnt];
            double[] doWhileVerifyList = new double[loopCnt];
            double[] doDoWhileVerifyList = new double[loopCnt];
            double[] doLINQQueryVerifyList = new double[loopCnt];
            double[] doLINQMethodVerifyList = new double[loopCnt];

            int[] verifyList = Enumerable.Repeat<int>(1, listCnt).ToArray();

            for(int i = 0; i < loopCnt; i++)
            {
                doForVerifyList[i] = DoForVerify(verifyList);
                doForEachVerifyList[i] = DoForEachVerify(verifyList);
                doWhileVerifyList[i] = DoWhileVerify(verifyList);
                doDoWhileVerifyList[i] = DoDoWhileVerify(verifyList);
                doLINQQueryVerifyList[i] = DoLINQQueryVerify(verifyList);
                doLINQMethodVerifyList[i] = DoLINQMethodVerify(verifyList);
            }
            //Output the average value of each
            Console.WriteLine("ForAvg:" + String.Format(resultFormat, doForVerifyList.Average()));
            Console.WriteLine("ForEachAvg:" + String.Format(resultFormat, doForEachVerifyList.Average()));
            Console.WriteLine("WhileAvg:" + String.Format(resultFormat, doWhileVerifyList.Average()));
            Console.WriteLine("DoWhileAvg:" + String.Format(resultFormat, doDoWhileVerifyList.Average()));
            Console.WriteLine("LINQQueryAvg:" + String.Format(resultFormat, doLINQQueryVerifyList.Average()));
            Console.WriteLine("LINQMethodAvg:" + String.Format(resultFormat, doLINQMethodVerifyList.Average()));
        }

        /// <summary>
        ///verification of for
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoForVerify(int[] _verifyList)
        {
            int total = 0;
            start = DateTime.Now;
            for (int i = 0; i <= _verifyList.Length - 1; i++)
            {
                total += _verifyList[i];
            }
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }

        /// <summary>
        ///Foreach verification
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoForEachVerify(int[] _verifyList)
        {
            int total = 0;
            start = DateTime.Now;
            foreach (int i in _verifyList)
            {
                total += i;
            }
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }

        /// <summary>
        ///while verification
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoWhileVerify(int[] _verifyList)
        {
            int total = 0;
            int i = 0;
            start = DateTime.Now;
            while (i <= _verifyList.Length - 1)
            {
                total += _verifyList[i];
                i++;
            }
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }

        /// <summary>
        /// do-while verification
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoDoWhileVerify(int[] _verifyList)
        {
            int total = 0;
            int i = 0;
            start = DateTime.Now;
            do
            {
                total += _verifyList[i];
                i++;
            }
            while (i <= _verifyList.Length - 1);
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }

        /// <summary>
        ///LINQ validation (query syntax)
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoLINQQueryVerify(int[] _verifyList)
        {
            start = DateTime.Now;
            int total = (
                from x in _verifyList
                select x
                ).Sum();
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }

        /// <summary>
        ///LINQ validation (method syntax)
        /// </summary>
        /// <param name="_verifyList">Validation array</param>
        /// <returns>Elapsed time (milliseconds)</returns>
        private static double DoLINQMethodVerify(int[] _verifyList)
        {
            start = DateTime.Now;
            int total = _verifyList
                .Sum(x => x);
            end = DateTime.Now;
            return (end - start).TotalMilliseconds;
        }
    }
}

Execution result

First time

ForAvg:387.8 ms
ForEachAvg:419.6 ms
WhileAvg:391.0 ms
DoWhileAvg:391.2 ms
LINQQueryAvg:1236.2 ms
LINQMethodAvg:1216.8 ms

Second time

ForAvg:375.6 ms
ForEachAvg:408.2 ms
WhileAvg:377.1 ms
DoWhileAvg:366.7 ms
LINQQueryAvg:1188.7 ms
LINQMethodAvg:1176.5 ms

Third time

ForAvg:354.1 ms
ForEachAvg:379.8 ms
WhileAvg:358.9 ms
DoWhileAvg:355.1 ms
LINQQueryAvg:1135.5 ms
LINQMethodAvg:1124.3 ms

Conclusion

The for statement was the fastest. Even without LINQ, the slowest foreach was a bit of a shock.
This time, I think that it was a disadvantageous verification condition for LINQ because there was no particular conditional branching in the iterative processing.
Therefore, I would like to perform verification based on them once again. ** Please look forward to the next time. **