Vous pouvez facilement voir comment .Net List
implémente la méthode Find
utilisant réflecteur:
Public Function Find(ByVal match As Predicate(Of T)) As T
If (match Is Nothing) Then
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match)
End If
Dim i As Integer
For i = 0 To Me._size - 1
If match.Invoke(Me._items(i)) Then
Return Me._items(i)
End If
Next i
Return CType(Nothing, T)
End Function
La seule différence entre les deux est que les implémentations Find
nécessite un appel à match
au lieu d'avoir cette logique inline dans la boucle.
Fait intéressant, cette simple performance:
var persons = new List<Person>();
for (int i = 0; i < 100; i++)
{
persons.Add(new Person { ID = i });
}
GC.Collect();
var sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
persons.Find(person => person.ID == i % 100);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
GC.Collect();
sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
for (int j = 0; j < 100; j++)
{
if (persons[j].ID == i % 100)
{
break;
}
}
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
montre que:
Temps total requis pour interroger la liste à l'aide Trouver est 05.7990078 secondes.
Temps total requis pour interroger la liste en utilisant boucle est 06.3551074 secondes.
Ce résultat semble cohérent dans plusieurs exécutions.
Modifier - explication trouvée pour l'avantage de Find
:
Find
fonctionne plus rapidement car il accède directement au tableau sous-jacent à chaque itération. L'accès à la boucle à travers le List
indexeur, ce qui nécessite pour chaque vérification de l'indice d'accès:
Public Default Property Item(ByVal index As Integer) As T
Get
If (index >= Me._size) Then
ThrowHelper.ThrowArgumentOutOfRangeException
End If
Return Me._items(index) // _items is the underlying array.
End Get
Essayez les deux approches en tant que micro référence. – Oded
L'application devrait effectuer un traitement en temps quasi-réel, par conséquent, même une différence de poils divisée signifierait quelque chose quand elle se cumule. Mais interne, si c'est toujours une boucle alors je ferais mieux de boucler moi-même et enregistrer l'appel de la fonction? –