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.
new SudokuPuzzle
In der ersten Version verwende ich den Ansatz new Puzzle(puzzle)
, um das Objekt zu klonen:
Wenn ich das Array aktualisiere, mache ich Folgendes:
%Vor%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()
:
Meine Update-Methode ist in diesem Fall
%Vor% Die erste Version, die new
verwendet, ist sehr schnell mit Knoten:
Die zweite Version, die Object.create()
verwendet, ist konsistent mehr als 10x langsamer:
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 .
Dank Bergis Antwort unten habe ich die Zeile in der Methode clone
von
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.
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 .
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.
Tags und Links javascript node.js