Je suis en train de faire des tests de performance et a constaté qu'une expression LINQ comme
result = list.First(f => f.Id == i).Property
est plus lent que
result = list.Where(f => f.Id == i).First().Property
Cela semble contre-intuitif. J'aurais pensé que la première expression serait plus rapide car il peut arrêter une itération sur la liste dès que le prédicat est satisfait, alors que j'aurais pensé que l' .Where()
expression peut itérer sur l'ensemble de la liste avant d'appeler .First()
sur le sous-ensemble. Même si celui-ci ne court-circuit, il ne devrait pas être plus rapide que d'utiliser directement pour la Première, mais il est.
Ci-dessous sont deux très simples tests unitaires qui illustrent cette situation. Lorsqu'il est compilé avec optimisation sur les TestWhereAndFirst est environ 30% plus rapide que TestFirstOnly .Net et Silverlight 4. J'ai essayé de faire le prédicat de retour plus de résultats, mais la différence de performance est la même.
Quelqu'un peut-il expliquer pourquoi .First(fn)
plus lente que l' .Where(fn).First()
? Je vois un semblable résultat contre-intuitif avec .Count(fn)
par rapport à l' .Where(fn).Count()
.
private const int Range = 50000;
private class Simple
{
public int Id { get; set; }
public int Value { get; set; }
}
[TestMethod()]
public void TestFirstOnly()
{
List<Simple> list = new List<Simple>(Range);
for (int i = Range - 1; i >= 0; --i)
{
list.Add(new Simple { Id = i, Value = 10 });
}
int result = 0;
for (int i = 0; i < Range; ++i)
{
result += list.First(f => f.Id == i).Value;
}
Assert.IsTrue(result > 0);
}
[TestMethod()]
public void TestWhereAndFirst()
{
List<Simple> list = new List<Simple>(Range);
for (int i = Range - 1; i >= 0; --i)
{
list.Add(new Simple { Id = i, Value = 10 });
}
int result = 0;
for (int i = 0; i < Range; ++i)
{
result += list.Where(f => f.Id == i).First().Value;
}
Assert.IsTrue(result > 0);
}