Frage

Ich arbeite mit einer Code-Basis, wo Listen müssen häufig für ein einzelnes Element gesucht werden.

Ist es schneller ein Prädikat zu verwenden und finden () als manuell auf der Liste eine Aufzählung zu tun?

Beispiel:

string needle = "example";
FooObj result = _list.Find(delegate(FooObj foo) {
    return foo.Name == needle;
});

vs.

string needle = "example";
foreach (FooObj foo in _list)
{
    if (foo.Name == needle)
        return foo;
}

Während sie in Funktionalität gleichwertig sind, sind sie in der Leistung gleichwertig auch?

War es hilfreich?

Lösung

Sie sind in der Leistung nicht gleichwertig. Die Find () -Methode erfordert ein Verfahren (in diesem Fall delegiert) Aufruf für jedes Element in der Liste. Methodenaufruf ist nicht frei und ist relativ teuer im Vergleich zu einem Inline-Vergleich. Die foreach-Version benötigt keinen zusätzlichen Methodenaufruf pro Objekt.

Dass gesagt wird, würde ich nicht das eine oder andere basierend auf der Leistung holen, bis ich meinen Code tatsächlich profilierte und fand dies ein Problem zu sein. Ich habe gefunden, noch nicht den Aufwand für dieses Szenario zu jedem für Code ein „heißen Pfad“ Problem sein, ich habe geschrieben, und ich benutze dieses Muster viel mit Suchen und anderen ähnlichen Verfahren.

Andere Tipps

Wenn Sie Ihre Liste der Suche zu langsam ist, wie sie ist, können Sie wahrscheinlich besser als eine lineare Suche. Wenn Sie die Liste sortiert halten können, können Sie eine binäre Suche verwenden Sie das Element in O (lg n) Zeit zu finden.

Wenn Sie suchen ein ganze Los, betrachtet diese Liste mit einem Wörterbuch ersetzt Ihre Objekte Index mit Namen.

Technisch wird die Laufzeit-Performance der Delegierten Version etwas schlechter ausfallen als die andere Version -. Aber in den meisten Fällen würden Sie sich schwer tun, einen Unterschied wahrnehmen

Von größerer Bedeutung (IHMO) ist der Code Zeit-Leistung in der Lage zu schreiben, was Sie wollen, und nicht, wie Sie es wollen. Das macht einen großen Unterschied in der Wartbarkeit.

Dieser ursprüngliche Code:

string needle = "example";
foreach (FooObj foo in _list)
{
    if (foo.Name == needle)        
        return foo;
}

erfordert jeden Betreuer, den Code zu lesen und verstehen, dass Sie für einen bestimmten Artikel suchen.

Dieser Code

string needle = "example";
return _list.Find(
    delegate(FooObj foo) 
    {
        return foo.Name == needle;
    });

macht deutlich, dass man für einen bestimmten Artikel suchen ist -. Schneller zu verstehen,

Schließlich dieser Code, mit Features von C # 3.0:

string needle = "example";
return _list.Find( foo => foo.Name == needle);

tut genau das Gleiche, aber in einer Linie, die schneller ist sogar zu lesen und verstehen (na ja, wenn Sie verstehen,

"Ich bin mit einer Code-Basis arbeiten, in dem Listen müssen werden häufig gesucht für ein einzelnes Element"

Es ist besser, Ihre Datenstruktur zu ändern Wörterbuch zu sein, anstatt Liste eine bessere Leistung zu erhalten

Als Jared wies darauf hin, gibt es Unterschiede.

Aber, wie immer, keine Sorge, wenn Sie wissen, dass es ein Engpass ist. Und wenn es ein Engpass ist, das ist wahrscheinlich, weil die Listen groß sind, in diesem Fall sollten Sie prüfen, mit einem schnellen finden - einer Hash-Tabelle oder binären Baum oder auch nur die Liste sortieren und binäre Suche zu tun gibt Sie lügen (n) Leistung, die weit mehr Auswirkungen als Tweaking Ihre linearen Fall haben wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top