Why is Node's Object.create(foo) much slower than new Foo()?

Viewed 220

I wrote a simple Sudoku solver using backtracking in JS. In effort to be "purely functional" all my 9x9 puzzle arrays are immutable thus a new array is created whenever a new number is inserted.

Version 1 using new SudokuPuzzle

In the first version I use the new Puzzle(puzzle) approach to clone the object:

function SudokuPuzzle(obj) {
   if (obj instanceof SudokuPuzzle) {
      this.grid = obj.grid.slice(0);  // copy array
   } // ...
}

Then whenever I update the array I do the following:

SudokuPuzzle.prototype.update = function(row, col, num) {
    var puzzle = new SudokuPuzzle(this); // clone puzzle
    puzzle.grid[row*9 + col] = num;      // mutate clone
    return puzzle;                       // return clone
}

Version 2 using Object.create()

I wrote another version where I use Object.create() instead and have a base object sudokuPuzzle that I inherit from to create new puzzles. Here is the clone() method:

sudokuPuzzle.clone = function() {
   var puzzle = Object.create(this); // create puzzle from sudokuPuzzle
   puzzle.grid = this.grid.slice(0); // copy array
   return puzzle;                    // return newly minted puzzle
}

My update method in this case is

sudokuPuzzle.update = function(row, col, num) {
   var puzzle = this.clone();       // clone puzzle
   puzzle.grid[row*9 + col] = num;  // mutate clone
   return puzzle;                   // return clone
}

Speed Tests

The first version using new is very fast using Node:

$ time node Sudoku.js
real    0m0.720s
user    0m0.699s
sys     0m0.016s

The second version using Object.create() is consistently over 10x slower:

$ time node Sudoku2.js
real        0m7.746s
user        0m7.647s
sys         0m0.091s

A similar question here noted that Object.create() is a lot slower in browsers, while I am also seeing a large disparity with node.js as well. I can certainly see timing discrepancies between JS engines, but a > 10x difference?!? Does anyone know why the difference is over an order of magnitude?!

You can find the source code here.

Update with Annotated Answer

Thanks to Bergi's answer below I changed the line in the clone method from

 var puzzle = Object.create(this); 

to this:

 var puzzle = Object.create(sudokuPuzzle); 

which avoids long and complex inheritance chains (i.e., I always inherit from the same base object) and I now get speed results comparable to using new. Thanks Bergi.

2 Answers
Related