Lambda-Funktionen vs. binden, Speicher! (und Leistung)

8

Ich möchte herausfinden, welches die beste Vorgehensweise zwischen gleichwertigen Lösungen ist. Der Anwendungsfall ist eine Instanz einer Klasse, die auf ein Ereignis hört. Dr. Axel Rauschmayer bevorzugt das Lambda zur besseren Lesbarkeit. Ich stimme ihm zu. Aber in Bezug auf Leistung und Speicherverbrauch, welches ist das Beste?

Mit einer Lambda-Funktion

%Vor%

Kann jemand bestätigen oder erschweren, ob die lokalen Variablen (hier el ) nicht vom Garbage Collector gelöscht werden können? Oder sind moderne Browser in der Lage zu erkennen, dass sie in der Schließung nicht verwendet werden?

Mit Function.prototype.bind :

%Vor%

Es gibt kein Speicherproblem, aber alle Benchmarks legen nahe, dass bind weit langsamer ist als eine Schließung (ein Beispiel dafür ist ) hier ).

BEARBEITEN: Ich stimme den Kommentaren nicht zu, die das Leistungsproblem von bind ignorieren. Ich empfehle, diese Antwort mit dem Code der Implementierung in Chrome zu lesen. Es kann nicht effizient sein. Und ich bestehe darauf: alle die Benchmarks, die ich gesehen habe, zeigen ähnliche Ergebnisse bei all Browsern.

Gibt es eine Möglichkeit, eine geringe Speichernutzung und gleichzeitig eine gute Leistung zu erzielen?

    
Paleo 08.02.2017, 16:00
quelle

1 Antwort

8

Closures (oder Pfeilfunktionen , aka lambdas ) verursachen keine Speicherlecks

  

Kann jemand bestätigen oder erschweren, ob die lokalen Variablen (hier el ) nicht vom Garbage Collector gelöscht werden können? Oder sind moderne Browser in der Lage zu erkennen, dass sie in der Schließung nicht verwendet werden?

Ja , moderne JavaScript-Engines sind in der Lage, Variablen aus übergeordneten Bereichen zu erkennen, die von einem Abschluss sichtbar sind, aber nicht verwendet werden. Ich habe einen Weg gefunden, das zu beweisen.

Schritt 1: Die Schließung verwendet eine Variable von 10 MB

Ich habe diesen Code in Chrom verwendet:

%Vor%

Beachten Sie die Variable arr vom Typ Uint8Array . Es ist ein typisiertes Array mit einer Größe von 10 Megabyte. In dieser ersten Version wird die Variable arr im Closure verwendet.

Dann nehme ich in den Entwickler-Tools von Chromium, Registerkarte "Profile", einen Heap-Snapshot :

Nach der Sortierung durch Verringerung der Größe lautet die erste Zeile: "system / JSArrayBufferData" mit einer Größe von 10 MB. Es ist unsere Variable arr .

Schritt 2: Die Variable von 10 MB ist sichtbar, aber nicht in der Schließung

Jetzt entferne ich einfach den Parameter arr in dieser Codezeile:

%Vor%

Dann ein zweiter Schnappschuss:

Die erste Zeile ist verschwunden.

Diese Erfahrung bestätigt, dass der Garbage Collector in der Lage ist, Variablen aus übergeordneten Bereichen zu bereinigen, die bei aktiven Closures zwar sichtbar, aber nicht verwendet werden.

Über Function.prototype.bind

Ich zitiere den Google JavaScript Style Guide , Abschnitt über die Pfeilfunktionen:

  

Rufen Sie niemals f.bind(this) oder goog.bind(f, this) auf (und vermeiden Sie es, const self = this zu schreiben). All diese können mit einer Pfeilfunktion deutlicher und weniger fehleranfällig ausgedrückt werden. Dies ist besonders nützlich für Rückrufe, die manchmal unerwartete zusätzliche Argumente übergeben.

Google empfiehlt eindeutig, lambdas statt Function.prototype.bind zu verwenden.

Verwandte:

Paleo 22.02.2017, 15:27
quelle

Tags und Links