15 Stimmen

In jQuery ist es effizienter, filter() zu verwenden, oder einfach so in der each() tun?

Ich habe derzeit Code, der in Daten über jQuery zieht und dann anzeigen es mit der each Methode.

Allerdings war ich in ein Problem mit der Sortierung laufen, so sah ich in mit, und fügte hinzu, jQuery's filter Methode vor der sort (was sinnvoll ist).

Ich überlege nun, die sort und ich frage mich, ob ich die filter Aufruf so wie er ist, oder verschieben Sie ihn zurück in die each .

Die Beispiele in der jQuery API-Dokumentation für Filter bei der Gestaltung von Ergebnissen bleiben, nicht bei der Ausgabe von Textinhalten (insbesondere nicht bei der Verwendung von each() ).

In der Dokumentation heißt es derzeit, dass "[t]he supplied selector is tested against each element [...]", was mich glauben lässt, dass eine filter et eine each würde dazu führen, dass nicht gefilterte Elemente zweimal in einer Schleife durchlaufen werden, während dies nur einmal der Fall wäre, wenn die Prüfung ausschließlich in der each Schleife.

Gehe ich recht in der Annahme, dass dies effizienter ist?

EDIT: Dummy-Beispiel.

Also dies:

// data is XML content
data = data.filter(function (a) {
    return ($(this).attr('display') == "true");
});
data.each(function () {
    // do stuff here to output to the page
});

Im Gegensatz zu diesem:

// data is XML content
data.each(function () {
    if ($(this).attr('display') == "true") {
        // do stuff here to output to the page
    }
});

16voto

Erick Petrucelli Punkte 13198

Genau wie Sie gesagt haben:

Die Dokumentation c dass "der mitgelieferte Selektor wird gegen jedes Element getestet [...]" , was mich zu der Annahme bringt, dass ein Filter und ein "Each" ergeben würde nicht gefilterte Elemente in einer Schleife wiedergegeben werden zweimal durchlaufen werden, anstatt nur einmal, wenn die Prüfung nur in der each Schleife erfolgt.

Anhand Ihres Codes können wir deutlich erkennen, dass Sie each in beiden Fällen ist das, was bereits ein Schleife . Und die filter selbst ist eine weitere Schleife (mit einem wenn es für die Filterung). Das heißt, wir vergleichen die Leistung zwischen zwei Schleifen con eine Schleife . Unvermeidlich weniger Schleifen = bessere Leistung .

Ich habe diese Fiedel und profiliert mit Firebug Profiling Werkzeug . Wie erwartet, ist die zweite Möglichkeit mit nur einer Schleife es schneller . Natürlich betrug der Unterschied bei dieser geringen Anzahl von Elementen nur 0,062 ms. Aber natürlich würde der Unterschied linear ansteigen mit mehr Elementen.

Da viele Leute sehr besorgt sind und sagen, der Unterschied sei gering und man solle sich nach der Wartbarkeit richten, fühle ich mich frei, meine Meinung zu äußern: Ich stimme dem auch zu. In der Tat denke ich, dass der wartbarere Code ohne den Filter ist, aber das ist nur eine Frage des Geschmacks. Schließlich ging es bei Ihrer Frage darum, was effizienter ist, und genau das wurde beantwortet, obwohl der Unterschied gering ist.

10voto

Raynos Punkte 162170

Sie haben Recht, dass die Verwendung von Filter und jeder ist langsamer. Schneller ist es, nur die each-Schleife zu verwenden. Optimieren Sie sie nach Möglichkeit so, dass weniger Schleifen verwendet werden.

Aber das ist eine Mikrooptimierung. Diese sollte nur optimiert werden, wenn sie "kostenlos" ist und nicht auf Kosten von lesbarem Code geht. Ich persönlich würde mich für das eine oder das andere entscheiden, weil ich den Stil und die Lesbarkeit bevorzuge und nicht die Leistung.

Wenn Sie nicht gerade eine riesige Menge an DOM-Elementen haben, werden Sie den Unterschied nicht bemerken (und wenn doch, dann haben Sie größere Probleme).

Und wenn Sie sich um diesen Unterschied kümmern, dann kümmern Sie sich darum, jQuery nicht zu verwenden, weil jQuery langsam ist.

Worauf Sie achten sollten, ist die Lesbarkeit und Wartbarkeit.

$(selector).filter(function() {
    // get elements I care about
}).each(function() {
    // deal with them
});

gegen

$(selector).each(function() {
    // get elements I care about
    if (condition) {
         // deal with them
    }
}

Je nachdem, was Ihren Code besser lesbar und wartbar macht, ist dies die optimale Wahl. Ein weiterer Hinweis: Filter sind viel leistungsfähiger, wenn sie mit .map dann bei Verwendung mit .each .

Ich möchte auch darauf hinweisen, dass die Optimierung von zwei Schleifen auf eine Schleife eine Optimierung von O(n) a O(n) . Das ist nichts, worüber Sie sich Gedanken machen sollten. In der Vergangenheit hatte ich auch das Gefühl, dass es "besser" ist, alles in eine Schleife zu packen, weil man nur einmal schleifen muss, aber das schränkt Sie bei der Verwendung von map/reduce/filter wirklich ein.

Schreiben Sie sinnvollen, selbstdokumentierenden Code. Optimieren Sie nur Engpässe.

3voto

James Montagne Punkte 75564

Ich würde erwarten, dass die Leistung hier sehr ähnlich ist, wobei die beiden etwas schneller sind (was wahrscheinlich bei großen Datensätzen auffällt, bei denen die gefilterte Menge noch groß ist). Filter wahrscheinlich nur Schleifen über die Menge sowieso (jemand korrigieren Sie mich, wenn ich falsch bin). Das erste Beispiel durchläuft also eine Schleife über die gesamte Menge und dann eine Schleife über die kleinere Menge. Das 2. Beispiel macht nur eine Schleife.

Am schnellsten geht es jedoch, wenn Sie den Filter in Ihren ursprünglichen Selektor aufnehmen. Nehmen wir also an, Ihre aktuelle Datenvariable ist das Ergebnis des Aufrufs $("div") . Anstatt das aufzurufen und es dann zu filtern, verwenden Sie zunächst dieses:

$("div[display='true']")

0voto

thdoan Punkte 17054

Ich mache mir im Allgemeinen keine Sorgen über Mikro-Optimierungen wie diese, da Sie sich im Großen und Ganzen wahrscheinlich viel mehr Sorgen um die Leistung als jQuery machen müssen .each() vs. .filter() aber um die vorliegende Frage zu beantworten, sollten Sie die besten Ergebnisse mit einer .filter() :

data.filter(function() {
  return ($(this).attr('display')==="true");
}).appendTo($('body'));

Für einen primitiven Leistungsvergleich zwischen .each() y .filter() können Sie sich diesen Codepen ansehen:

http://codepen.io/thdoan/pen/LWpwwa

Wenn Sie jedoch nur versuchen, alle Knoten auszugeben, die display="true" auf die Seite, dann können Sie einfach wie von James Montagne vorgeschlagen vorgehen (vorausgesetzt, der Knoten ist <element> ):

$('element[display=true]').appendTo($('body'));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X