Warum ist Object.create (foo) von Node viel langsamer als das neue Foo ()?

8

Ich habe einen einfachen Sudoku-Solver geschrieben, der Backtracking in JS verwendet. Im Bemühen, "rein funktional" zu sein, sind alle meine 9x9-Puzzle-Arrays unveränderlich, so dass jedes Mal, wenn eine neue Nummer eingefügt wird, ein neues Array erstellt wird.

Version 1 mit new SudokuPuzzle

In der ersten Version verwende ich den Ansatz new Puzzle(puzzle) , um das Objekt zu klonen:

%Vor%

Wenn ich das Array aktualisiere, mache ich Folgendes:

%Vor%

Version 2 mit Object.create()

Ich habe eine andere Version geschrieben, in der ich stattdessen Object.create() verwende und ein Basisobjekt sudokuPuzzle habe, von dem ich erben kann, um neue Puzzles zu erstellen. Hier ist die Methode clone() :

%Vor%

Meine Update-Methode ist in diesem Fall

%Vor%

Geschwindigkeitstests

Die erste Version, die new verwendet, ist sehr schnell mit Knoten:

%Vor%

Die zweite Version, die Object.create() verwendet, ist konsistent mehr als 10x langsamer:

%Vor%

Eine ähnliche Frage hier zur Kenntnis genommen Das Object.create() ist in Browsern viel langsamer, während ich auch eine große Disparität mit node.js sehe. Ich kann sicherlich Timing Diskrepanzen zwischen JS-Engines sehen, aber ein & gt; 10x Unterschied?!? Weiß jemand, warum der Unterschied über eine Größenordnung liegt?!

Hier finden Sie den Quellcode .

Aktualisierung mit kommentierter Antwort

Dank Bergis Antwort unten habe ich die Zeile in der Methode clone von

geändert %Vor%

dazu:

%Vor%

vermeidet lange und komplexe Vererbungsketten (d. h. ich erben immer vom selben Basisobjekt) und erhalte jetzt Geschwindigkeitsergebnisse, die mit denen von new vergleichbar sind. Danke Bergi.

    
wcochran 23.03.2016, 16:26
quelle

2 Antworten

4

Sie haben bereits festgestellt, dass V8 Object.create nicht so gut wie new (im Gegensatz zu SpiderMonkey) optimiert. Oder zumindest historisch. Siehe auch diesen Blogeintrag für Details .

Es gibt jedoch einen zweiten Grund dafür, dass dies viel langsamer ist: Ihre zwei Codes haben unterschiedliche Ergebnisse. Sie müssten

verwenden %Vor%

erstellt Klone, die denen entsprechen, die mit new SudokuPuzzle() erstellt wurden.

Das Problem ist, dass wenn Sie Object.create(this) verwenden, Sie ein neues Objekt erstellen, das einen anderen Prototyp hat - nämlich die this -Instanz. Wenn Sie sehr oft klonen, erstellen Sie eine sehr komplexe Vererbungshierarchie. Und all diese Objekte mit verschiedenen Prototypen werden verschiedene versteckte Klassen haben - welche verhindert Optimierungen .

    
Bergi 23.03.2016, 17:03
quelle
0

Sie können andere Beiträge Object.create und new vergleichen, für mich ist es Intuition - Wenn Sie das Schlüsselwort new verwenden, weiß die Engine, was sie erstellen möchte. Wenn Sie Object.create verwenden, muss die Engine zusätzliche Arbeit leisten, um den Typ zu überschreiben, ...

Wie es in der Post geschrieben ist, wenn Sie nur ein paar Objekte erstellen, sollte die Leistung keine Rolle spielen (7s? wirklich?). Allerdings - JS ist nicht wirklich für die Reflexion gebaut. Also Methoden this.clone () oder Object.create (this) sind wirklich nicht effektiv.

    
gusto2 23.03.2016 17:00
quelle

Tags und Links