Click here to Skip to main content
Click here to Skip to main content

Comparison between Different Methods to Iterate Over a List of Items

By , 7 Mar 2011
 
LoopExecutionComparison.zip
LoopExecutionComparison
Local.testsettings
LoopExecution.Application
LoopExecution.Application.csproj.vs10x
Properties
LoopExecution.Library
LoopExecution.csproj.vs10x
LoopExecution.Library.csproj.vs10x
Properties
LoopExecution.Test
LoopExecution.Test.csproj.vs10x
Properties
LoopExecutionComparison.suo
LoopExecutionComparison.vsmdi
TestResults
ThreadResultsWriteLine.csv
ThreadReultsSleep.csv
TraceAndTestImpact.testsettings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace LoopExecution
{

    public class LoopExecution<T>
    {

        public delegate void MethodToExecute(object sender, LoopExecutionEventArgs e);
        public event MethodToExecute ExecutionMethod;

        protected void OnExecuteMethod(object sender, LoopExecutionEventArgs e)
        {
            if (ExecutionMethod != null)
            {
                ExecutionMethod(sender, e);
            }
        }

        public List<T> CollectionToIterateOver { get; set; }

        public long NormalLoopTime { get; set; }
        public long ThreadLoopTime { get; set; }
        public long ThreadPoolLoopTime { get; set; }
        public long TaskLoopTime { get; set; }
        Stopwatch watch = new Stopwatch();

        public void Execute()
        {
            NormalExecute();
            ThreadExecute();
            ThreadPoolExecute();
            TaskParallelExecute();
        }

        private void NormalExecute()
        {
            watch.Start();
            NormalWhileLoop();
            NormalLoopTime = watch.ElapsedMilliseconds;
            watch.Reset();
        }

        private void NormalWhileLoop()
        {
            for (int i = 0; i < this.CollectionToIterateOver.Count; i++)
            {
                LoopExecutionEventArgs e = new LoopExecutionEventArgs();
                StackFrame stackFrame = new StackFrame();
                e.MethodName = stackFrame.GetMethod().ToString();
                e.LoopExecutionNumber = i;
                e.ObjectToOperateOn = CollectionToIterateOver[i];

                OnExecuteMethod(this, e);
            }
        }

        private void ThreadExecute()
        {
            watch.Start();
            ThreadLoop();
            ThreadLoopTime = watch.ElapsedMilliseconds;
            watch.Reset();
        }

        private void ThreadLoop()
        {

            for (int i = 0; i < this.CollectionToIterateOver.Count; i++)
            {
                Thread t = new Thread(x =>
                {
                    LoopExecutionEventArgs e = new LoopExecutionEventArgs();
                    StackFrame stackFrame = new StackFrame();
                    e.MethodName = stackFrame.GetMethod().ToString();
                    e.LoopExecutionNumber = (int)x;
                    e.ObjectToOperateOn = CollectionToIterateOver[(int)x];
                    OnExecuteMethod(this, e);
                });
                t.Start(i);
            }
        }

        private void ThreadPoolExecute()
        {
            watch.Start();
            ThreadPoolLoop();
            ThreadPoolLoopTime = watch.ElapsedMilliseconds;
            watch.Reset();
        }
        
        private void ThreadPoolLoop()
        {
            int toProcess = this.CollectionToIterateOver.Count;
            using (ManualResetEvent resetEvent = new ManualResetEvent(false))
            {
                for (int i = 0; i < this.CollectionToIterateOver.Count; i++)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(x =>
                        {
                            LoopExecutionEventArgs e = new LoopExecutionEventArgs();
                            StackFrame stackFrame = new StackFrame();
                            e.MethodName = stackFrame.GetMethod().ToString();
                            e.LoopExecutionNumber = (int)x;
                            e.ObjectToOperateOn = CollectionToIterateOver[(int)x];
                            OnExecuteMethod(this, e);
                            if (Interlocked.Decrement(ref toProcess) == 0)
                                resetEvent.Set();

                        }
                                 ), i);
                }
                resetEvent.WaitOne();
            }
        }

        private void TaskParallelExecute()
        {
            watch.Start();
            TaskParallelLibraryLoop();
            TaskLoopTime = watch.ElapsedMilliseconds;
            watch.Reset();
        }

        private void TaskParallelLibraryLoop()
        {
            Parallel.For(0, this.CollectionToIterateOver.Count, i =>
                {
                    LoopExecutionEventArgs e = new LoopExecutionEventArgs();
                    StackFrame stackFrame = new StackFrame();
                    e.MethodName = stackFrame.GetMethod().ToString();
                    e.LoopExecutionNumber = i;
                    e.ObjectToOperateOn = CollectionToIterateOver[i];
                    OnExecuteMethod(this, e);
                })
            ;
        }

        public class LoopExecutionEventArgs : EventArgs
        {
            public String MethodName { get; set; }
            public T ObjectToOperateOn { get; set; }
            public int LoopExecutionNumber { get; set; }
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of use and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Michael Bookatz
Software Developer
United Kingdom United Kingdom
Member
I'm a software developer with 4 years experience of using C# and Microsoft SQL server.
 
I work on line of business desktop applications that cross the entire development stack with the full development life cycle.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 8 Mar 2011
Article Copyright 2011 by Michael Bookatz
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid