Does using anonymous functions use performance?

I was wondering if there is a performance difference between named functions and anonymous functions in Javascript?

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

against

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

The first one is tidier since it does not clutter up your code with rarely used functions, but does it matter that you re-declare this function several times?

+72
performance optimization javascript
Sep 17 '08 at 7:28
source share
12 answers

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

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

You create a thousand different function objects, although they have the same code and are not attached to the lexical area ( closure ). On the other hand, it looks faster, because it just assigns the same function to reference the elements of the array during the loop:

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

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

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

In short, there is no observable operational cost of using anonymous over named functions.

Aside, it may seem from above that there is no difference between:

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

and

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

The first is a function declaration, and the second is the assignment of a variable to an anonymous function. Although they may have the same effect, JavaScript handles them a little differently. To understand the difference, I recommend reading the " ambiguity of declaring JavaScript functions .

The actual runtime for any approach will be largely determined by the implementation of the compiler browser and runtime. For a complete comparison of current browser performance, visit the JS Perf website

+74
Sep 17 '08 at 9:07
source share

Here is 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)); } 

Results:
Test 1: 142 ms Test 2: 1983 m.

It seems that the JS engine does not recognize that it has the same function in Test2 and compiles it every time.

+20
Sep 17 '08 at 7:52
source share

As a general design principle, you should avoid repeating the same code several times. Instead, you should output the general code to a function and execute this (general, well-tested, easily modifiable) function from several places.

If (unlike what you are doing from your question), you declare an internal function once and use this code once (and have nothing else in your program), then you can use an autonomous function, which is probably the path of the compiler as a normal named function.

This is a very useful feature in certain cases, but should not be used in many situations.

+2
Sep 17 '08 at 7:33
source share

I would not expect much difference, but if there is one, it will most likely be changed using a scripting mechanism or a browser.

If you find that the code is simpler, performance is not a problem unless you want to call this function millions of times.

+1
Sep 17 '08 at 7:36
source share

Anonymous objects are faster than named objects. But calling more functions is more expensive and to such an extent that it overshadows any savings you can get from using anonymous functions. Each function is called adding a call stack that introduces a small but non-trivial amount of overhead.

But if you do not write encryption / decryption procedures or something similar to performance, as many others have noted, it is always better to optimize for elegant, easy to read code with fast code.

Assuming you're writing well-designed code, then speed issues should answer those who write interpreters / compilers.

+1
Sep 17 '08 at 14:15
source share

In cases where we can have an impact on performance, we work with function declarations. Here is a template for declaring functions inside the context of another function or outside:

http://jsperf.com/function-context-benchmark

In Chrome, the operation is faster if we declare the function from the outside, but in Firefox it is the other way around.

In another example, we see that if the internal function is not a pure function, there will also be no performance in Firefox: http://jsperf.com/function-context-benchmark-3

+1
Nov 24 '15 at 21:29
source share

Which will definitely make your cycle faster in different browsers, especially IE browsers, will be cyclic:

 for (var i = 0, iLength = imgs.length; i < iLength; i++) { // do something } 

You entered an arbitrary 1000 in the loop condition, but you will get my drift if you want to view all the elements in the array.

0
Sep 17 '08 at 7:44
source share

@nickf

This is a rather disgusting test, although you are comparing the execution and compilation times there, which obviously will cost method 1 (compiles N times, the JS engine depends) with method 2 (compilation once). I cannot imagine a JS developer who would pass code for probing in this way.

A much more realistic approach is to use an anonymous task, since you are actually using document.onclick for your method more like the following, which actually gently supports the anon method.

Using a similar test structure for yours:




 function test(m) { for (var i = 0; i < 1000000; ++i) { m(); } } function named() {var x = 0; x++;} var test1 = named; var test2 = function() {var x = 0; x++;} document.onclick = function() { var start = new Date(); test(test1); var mid = new Date(); test(test2); var end = new Date(); alert ("Test 1: " + (mid - start) + "ms\n Test 2: " + (end - mid) + "ms"); } 
0
Sep 17 '08 at 8:40
source share

a link will almost always be slower than what it refers to. Think of it this way: let's say you want to print the result of adding 1 + 1. Which makes sense:

 alert(1 + 1); 

or

 a = 1; b = 1; alert(a + b); 

I understand that this is actually an easy way to look at it, but it is illustrative, isn't it? Use the link only if it will be used several times - for example, which of these examples makes sense:

 $(a.button1).click(function(){alert('you clicked ' + this);}); $(a.button2).click(function(){alert('you clicked ' + this);}); 

or

 function buttonClickHandler(){alert('you clicked ' + this);} $(a.button1).click(buttonClickHandler); $(a.button2).click(buttonClickHandler); 

The second is best practice, even if it got more rows. I hope all this will be useful. (and jquery syntax didn't drop anyone)

0
Sep 17 '08 at 9:11
source share

YES! Anonymous functions are faster than regular functions. Perhaps if speed is paramount ... more important than code reuse, then consider using anonymous functions.

There is a good article on optimizing javascript and anonymous functions here:

http://dev.opera.com/articles/view/efficient-javascript/?page=2

0
Sep 17 '08 at 9:32 a.m.
source share

@nickf

(I wish I just wrote a comment, but I just found this site)

My point is that there is confusion between named / anonymous functions and the use-case + compilation use case for iteration. As I illustrated, the difference between the name anon + is negligible in itself - I say that this is a wrong use case.

It seems obvious to me, but if not, I think that the best advice is to β€œnot do stupid things” (of which constantly moving the block + creating an object of this use case is one), and if you are not sure, test!

0
Sep 17 '08 at 10:14
source share

As stated in the comments to @nickf's answer: Reply to

Creates a function one time faster than creating it a million times

just yes. But, as his JS perf shows, he does not slow down by a million, showing that with time he becomes faster.

A more interesting question for me:

How create + run is repeated to create once + restarted.

If a function performs complex calculations, the creation time of the function object is likely to be negligible. But what about creating a title in cases where it works fast? For example:

 // Variant 1: create once function adder(a, b) { return a + b; } for (var i = 0; i < 100000; ++i) { var x = adder(412, 123); } // Variant 2: repeated creation via function statement for (var i = 0; i < 100000; ++i) { function adder(a, b) { return a + b; } var x = adder(412, 123); } // Variant 3: repeated creation via function expression for (var i = 0; i < 100000; ++i) { var x = (function(a, b) { return a + b; })(412, 123); } 

This JS Perf shows that creating a function is one time faster than expected. However, even with a very fast operation, such as a simple addition, the overhead of creating a function several times.

The difference is likely to become significant only in cases where the creation of a functional object is complicated and at the same time an insignificant runtime is supported, for example, if the whole function body is wrapped in if (unlikelyCondition) { ... } .

0
Jun 17 '17 at 9:21 on
source share



All Articles