Friday, May 27, 2011

for loop vs foreach vs fordelegate vs LINQ vs Lambda loops

By seeing below report foreach is almost equal to lambda expression

Report - each Method 10 Iteration
Method Name : For :52
Method Name : ForEach :29
Method Name : ForEachDelegate :25
Method Name : Linq :37
Method Name : Lambda :33


Important - Run the code in Release Mode


static void Main(string[] args)
{
Test t = new Test();
t.AllTests();
}

class Avg
{
public int Time { get; set; }
public string MethodName { get; set; }
}

class Test
{
delegate void TestMethod();
List m_Source = new List();
List Average = new List();
System.Diagnostics.Stopwatch m_Watch
= new System.Diagnostics.Stopwatch();

public void AllTests()
{
for (int i = 0; i < 1000000; i++)
m_Source.Add(i);
TestMethod _TestFor = new TestMethod(TestFor);
TestMethod _TestForEach = new TestMethod(TestForEach);
TestMethod _TestForEachDelegate = new TestMethod(TestForEachDelegate);
TestMethod _TestLinq = new TestMethod(TestLinq);
TestMethod _TestLambda = new TestMethod(TestLambda);
//TestMethod _TestParallel = new TestMethod(TestParallel);

// how many time to repeat each test?

for (int i = 1; i < 10; i++)
{
TestThis(_TestFor);
TestThis(_TestForEach);
TestThis(_TestForEachDelegate);
TestThis(_TestLinq);
TestThis(_TestLambda);
//TestThis(_TestParallel);
Console.WriteLine(string.Empty);
}
var a1 = (from a in Average
group a by a.MethodName into g
select new { MethodName = g.Key, AvgTime = g.Sum(a2 => a2.Time) / g.Count() }).ToList();

foreach (var g in a1)
{
Console.WriteLine("Method Name : {0} :{1}", g.MethodName, g.AvgTime);
}

Console.Read();
}

void TestThis(TestMethod test)
{
m_Watch.Reset();
m_Watch.Start();
test.Invoke();
var _Time = (int)m_Watch.Elapsed.TotalMilliseconds;
var _Method = test.Method.Name.Replace("Test", string.Empty);
var _Result = string.Format("{1}\t{0}", _Method, _Time);
Average.Add(new Avg() { MethodName = _Method, Time = _Time });
Console.WriteLine(_Result);
}

void TestFor()
{
var _Target = new List();
for (int i = 0; i < m_Source.Count(); i++)
_Target.Add(m_Source[i] + 1);
_Target.ToArray().Count();
//Debug.Assert(m_Source.Count() == _Target.ToArray().Count());
}

void TestForEach()
{
var _Target = new List();
foreach (int i in m_Source)
_Target.Add(i + 1);

_Target.ToArray().Count();
//Debug.Assert(m_Source.Count() == _Target.ToArray().Count());
}

void TestForEachDelegate()
{
var _Target = new List();
m_Source.ForEach((int i) =>
{
_Target.Add(i + 1);
});
_Target.ToArray().Count();
//Debug.Assert(m_Source.Count() == _Target.ToArray().Count());
}

void TestLinq()
{
var _Target = from i in m_Source
select i + 1;
_Target.ToArray().Count();
//Debug.Assert(m_Source.Count() == _Target.ToArray().Count());
}

void TestLambda()
{
var _Target = m_Source.Select(i => i + 1);
_Target.ToArray().Count();
//Debug.Assert(m_Source.Count() == _Target.ToArray().Count());
}

void TestParallel()
{
// TODO
}
}