Reputation: 466
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
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;
}
Upvotes: 1
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