Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does use of anonymous functions affect performance?

I've been wondering, is there a performance difference between using named functions and anonymous functions in Javascript?

for (var i = 0; i < 1000; ++i) {
    myObjects[i].onMyEvent = function() {
        // do something
    };
}

vs

function myEventHandler() {
    // do something
}

for (var i = 0; i < 1000; ++i) {
    myObjects[i].onMyEvent = myEventHandler;
}

The first is tidier since it doesn't clutter up your code with rarely-used functions, but does it matter that you're re-declaring that function multiple times?

like image 607
nickf Avatar asked Sep 17 '08 07:09

nickf


People also ask

Are anonymous functions bad?

Nope, anonymous functions are used all over the place in JavaScript across the web. It may make debugging a little more difficult in spots, but not nearly enough to say that they shouldn't be used. For example, JQuery makes extensive use of them.

Should you use anonymous functions?

The advantage of an anonymous function is that it does not have to be stored in a separate file. This can greatly simplify programs, as often calculations are very simple and the use of anonymous functions reduces the number of code files necessary for a program.

What does an anonymous function do?

An anonymous function is a function that is not stored in a program file, but is associated with a variable whose data type is function_handle . Anonymous functions can accept multiple inputs and return one output. They can contain only a single executable statement.

Why are anonymous functions frequently used with event handlers?

More generally, the point of using anonymous functions is that they do not require a name, because they are "event handlers" bound to a specific event on a specific object. In this case, the object is the entire Document Object Model, and the anonymous function executes when the entire DOM has loaded.


4 Answers

The performance problem here is the cost of creating a new function object at each iteration of the loop and not the fact that you use an anonymous function:

for (var i = 0; i < 1000; ++i) {         myObjects[i].onMyEvent = function() {         // do something         }; } 

You are creating a thousand distinct function objects even though they have the same body of code and no binding to the lexical scope (closure). The following seems faster, on the other hand, because it simply assigns the same function reference to the array elements throughout the loop:

function myEventHandler() {     // do something }  for (var i = 0; i < 1000; ++i) {     myObjects[i].onMyEvent = myEventHandler; } 

If you were to create the anonymous function before entering the loop, then only assign references to it to the array elements while inside the loop, you will find that there is no performance or semantic difference whatsoever when compared to the named function version:

var handler = function() {     // do something     }; for (var i = 0; i < 1000; ++i) {         myObjects[i].onMyEvent = handler; } 

In short, there is no observable performance cost to using anonymous over named functions.

As an aside, it may appear from above that there is no difference between:

function myEventHandler() { /* ... */ } 

and:

var myEventHandler = function() { /* ... */ } 

The former is a function declaration whereas the latter is a variable assignment to an anonymous function. Although they may appear to have the same effect, JavaScript does treat them slightly differently. To understand the difference, I recommend reading, “JavaScript function declaration ambiguity”.

The actual execution time for any approach is largely going to be dictated by the browser's implementation of the compiler and runtime. For a complete comparison of modern browser performance, visit the JS Perf site

like image 173
5 revs, 3 users 71% Avatar answered Oct 05 '22 20:10

5 revs, 3 users 71%


Here's my test code:

var dummyVar; function test1() {     for (var i = 0; i < 1000000; ++i) {         dummyVar = myFunc;     } }  function test2() {     for (var i = 0; i < 1000000; ++i) {         dummyVar = function() {             var x = 0;             x++;         };     } }  function myFunc() {     var x = 0;     x++; }  document.onclick = function() {     var start = new Date();     test1();     var mid = new Date();     test2();     var end = new Date();     alert ("Test 1: " + (mid - start) + "\n Test 2: " + (end - mid)); } 

The results:
Test 1: 142ms Test 2: 1983ms

It appears that the JS engine doesn't recognise that it's the same function in Test2 and compiles it each time.

like image 38
nickf Avatar answered Oct 05 '22 21:10

nickf


As a general design principle, you should avoid implimenting the same code multiple times. Instead you should lift common code out into a function and execute that (general, well tested, easy to modify) function from multiple places.

If (unlike what you infer from your question) you are declaring the internal function once and using that code once (and have nothing else identical in your program) then an anonomous function probably (thats a guess folks) gets treated the same way by the compiler as a normal named function.

Its a very useful feature in specific instances, but shouldn't be used in many situations.

like image 33
Tom Leys Avatar answered Oct 05 '22 19:10

Tom Leys


I wouldn't expect much difference but if there is one it will likely vary by scripting engine or browser.

If you find the code easier to grok, performance is a non-issue unless you expect to call the function millions of times.

like image 32
Joe Skora Avatar answered Oct 05 '22 19:10

Joe Skora