Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting functions and performance in javascript?

Some of coworkers are saying that nesting functions is bad for performance and I wanted to ask about this.

Lets say I have the function:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}

helper is a private function that is only used inside calculateStuff. That's why I wanted to encapsulate this inside calculateStuff.

Is this worse performance wise than doing:

function helper() {

}

function calculateStuff() {
    helper();
}

Notice that in the second case, I expose helper to my scope.

like image 405
user1413969 Avatar asked Oct 20 '15 23:10

user1413969


People also ask

What is nesting of functions give an example?

The nested function's name is local to the block where it is defined. For example, here we define a nested function named square, and call it twice: foo (double a, double b) { double square (double z) { return z * z; } return square (a) + square (b); }

What is difference between nested function and closure in JavaScript?

A closure is a function, which uses the scope in which it was declared when invoked. It is not the scope in which it was invoked. JavaScript 1.2 allows function definitions to be nested within other functions as well. Still, there is a restriction that function definitions may not appear within loops or conditionals.

Should you nest functions in JavaScript?

In theory, this could decrease performance if the parent function is called frequently. But, nested functions are very much used in Javascript. For example, closures are extremely powerful and should be understood by all JavaScript developers. Nesting has nothing to do with the stack.


2 Answers

In theory, there's a potential performance impact, in that you need to create a new closure context for helper every time calculateStuff is called (because it might reference variables from the enclosing scope).

I'm pretty sure that the JIT compiler in most JavaScript engines should be able to tell that you aren't actually accessing any variables from the parent context, and just skip binding all of those values. I may be missing some edge case where this isn't generally possible, but it seems straighforward-enough.

In any case, we're talking about nanoseconds of overhead per iteration, so unless your code is executed a lot, you'd never notice the time difference. If in doubt, profile it and check...


I decided to follow my own advice, and profile this on jsperf, with Safari 9. I used the do-nothing functions as provided in the original question, to highlight the overhead of just calling a nested function:

Nested functions: 136,000,000 calls per second

Flat functions: 1,035,000,000 cals per second

Oriol's IIFE version: 220,000,000 cals per second

Clearly the flat functions are much faster than either of the alternative versions. However, think about the magnitude of those numbers - even the "slow" version only adds 0.007 microseconds to the execution time. If you do any kind of calculation or DOM manipulation in that function, it'll absolutely dwarf the overhead of the nested function.

like image 61
Mark Bessey Avatar answered Nov 05 '22 01:11

Mark Bessey


With your first code, at each call of calculateStuff, a new copy of helper will be created.

With your second code, all calls will share the same helper, but it will pollute the outer scope.

If you want to reuse helper without polluting the outer scope, you can use an IIFE:

var calculateStuff = (function () {
  function helper() {
    // helper does things
  }
  return function() {
    // calculateStuff does things
    helper();
  }
})();
like image 25
Oriol Avatar answered Nov 05 '22 02:11

Oriol