I was performing some performance tests between various ways of checking which objects are in one list, but not in the other. And I came up with a result I did not expect, the average time for executing the same action using lambda was the highest between while, for, foreach, and lambda.
Code used:
// Object
public class ComplexObject
{
public int Number { get; set; }
public char Character { get; set; }
}
// Lists
private readonly List<ComplexObject> _complexList1 = new List<ComplexObject>();
private readonly List<ComplexObject> _complexList2 = new List<ComplexObject>();
/* Fills in lists with numbers from 0 to 100000 and characters from 0 to 50.
* The first list contains 10000 records and a second list contains 1000 records. */
private void FillLists()
{
var rnd = new Random();
for (int i = 0; i < 100000; i++)
{
_complexList1.Add(new ComplexObject
{
Number = rnd.Next(5000),
Character = (char)rnd.Next(50)
});
}
for (int i = 0; i < 1000; i++)
{
_complexList2.Add(new ComplexObject
{
Number = rnd.Next(5000),
Character = (char)rnd.Next(50)
});
}
}
// For
public void ExecuteFor()
{
var result = new List<ComplexObject>();
for (int countList2 = 0; countList2 < _complexList2.Count; countList2++)
{
bool found = false;
for (int countList1 = 0; countList1 < _complexList1.Count; countList1++)
{
if (_complexList2[countList2].Number == _complexList1[countList1].Number &&
_complexList2[countList2].Character == _complexList1[countList1].Character)
{
found = true;
break;
}
}
if (!found)
result.Add(_complexList2[countList2]);
}
}
// Foreach
public void ExecuteForeach()
{
var result = new List<ComplexObject>();
foreach (ComplexObject object2 in _complexList2)
{
bool found = false;
foreach (ComplexObject object1 in _complexList1)
{
if (object2.Number == object1.Number &&
object2.Character == object1.Character)
{
found = true;
break;
}
}
if (!found)
result.Add(object2);
}
}
// Lambda
public void ExecuteLambda()
{
var result =
_complexList2.Count(
l2 => _complexList1.All(l1 => l2.Number != l1.Number || l2.Character != l1.Character));
}
Using StopWatch to measure the time and running each loop type 10 times and taking the average execution time, the results were as follows:
For:10.163.836 ticks in avarage
Foreach:8.747.627 ticks in avarage
Lambda:14.326.094 ticks in avarage
The question is:
Are there other ways to solve my problem?
Does Lambda really spend more time than ordinary loops like foreach?