killexe
killexe

Reputation: 466

Is there a difference in performance if accessing properties differently in javascript?

Imagine a tree-like object obj1 which you want to access this way

obj1[prop1"]["prop1_1"]["prop1_1_1"] //do something

But I don't want to access it directly, so I wrote a recursive function to help me access any property of any child element of this object, something like this:

function getProperty(obj, path) {
  if(path.length == 1)
    return obj[path[0]];
  return getProperty(obj[path[0]], path.slice(1));
}

And now I call it like this: getProperty(obj1, ["prop1", "prop1_1", "prop1_1_1"])

Is there any performance difference between accessing it directly and accessing it with my recursive function other than the function call (and the slice)?

PS: The reason why I need this is, is that I want to access nested properties but I don't know if these properties exists and if not I want to return a default value. I didn't implement this in the function above to make it easier to read.

Upvotes: 1

Views: 73

Answers (2)

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

Using a loop instead of a recursion is sure improving the getProperty function, but it won't be as performant as getting the property directly:

function getProperty(obj, path) {
    for(var i = 0; i < path.length && obj; i++)
        obj = obj[ path[i] ];
    return obj;
}

JSPerf results.

Upvotes: 1

Junbang Huang
Junbang Huang

Reputation: 1967

So accessing it directly has the better performance than using a function and recursion. This make sense because when calling a function, the operating system has to do some preparation for you. If you know assembly, it actually copying necessary memory data first before calling the function. The following benchmark shows the result.

'use strict';

var obj = {
  prop1: {
    prop1_1: {
      prop1_1_1: 'hi'
    }
  }
};

var start = new Date();
for (var i = 0; i < 1000000; i++) {
  obj["prop1"]["prop1_1"]["prop1_1_1 "];
}
var duration1 = new Date() - start;

function getProperty(obj, path) {
  if (path.length == 1)
    return obj[path[0]];
  return getProperty(obj[path[0]], path.slice(1));
}

var start = new Date();
for (var i = 0; i < 1000000; i++) {
  getProperty(obj, ["prop1", "prop1_1", "prop1_1_1"]);
}
var duration2 = new Date() - start;

// duration1 < duration2
console.log(duration1);
console.log(duration2);

Upvotes: 2

Related Questions