Does Use of Anonymous Functions Affect Performance

Does use of anonymous functions affect performance?

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

Effect of Anonymous function in performance in Dart

Short Answer

No. It doesn't improve overall performance and also doesn't decrease memory usage. However the exact opposite might happen depending on the scenario.

Long Answer

Anonymous functions are the same as closures in Dart, and so will have a pointer(memory address) to the parent environment associated with it. Which means an additional variable with size equivalent to the bit-width of a pointer (in the corresponding platform) will be accompanying the anonymous function.

Memory

Here's how call to different types of functions work

  • Normal function: The arguments for the functions are the only values passed for the call.
  • Anonymous functions: The arguments for the functions are passed along with the pointer/reference to the parent's environment
  • Class method: A pointer/reference to the particular object instance is passed as the first argument along with the rest of the arguments.
  • Static Class method: This is equivalent to a normal function and the object instance of the class is not passed at all.

So, both class methods and anonymous functions have an extra variable, essentially a pointer, required to work. So "technically" this increases memory usage. However you don't have to worry about such things when you are using Dart. Because the extra memory required for anonymous functions and class methods is almost equivalent to when you add a new argument int newArg to a normal function or static class method.

If the anonymous function is executed right after it is declared, like (() {})(), then the pointer associated with it should be cleared in the next garbage collection sweep. This of course depends on the implementation and the scenario. If the anonymous function is stored in a variable or passed as an argument, then the lifetime of the pointer depends on the lifetime of that variable or argument.

Also, the pointer refers to the parent environment and because of this, the variables belonging to the parent scope, referred in the anonymous function will be kept alive even if the execution of the parent scope is complete. This in fact means that less memory is cleared in the next garbage collection sweep. The memory allocated for those referred variables will be cleared only when the anonymous function itself is not required anymore.

Performance

In the case of anonymous functions, there is also the need for lookup of parent-scoped variables used in the function body, that is the lookup for all the variables that are from the parent environment, this adds to compile-time or runtime depending on whether your dart code is AOT or JIT compiled.
But the same thing happens with normal class methods, as there is a need to lookup all class members used. (This doesn't happen in languages like Rust, Python... where there is a keyword like self or this representing the object instance that has to be explicitly mentioned)

Additional Context

Anonymous functions are otherwise referred to as lambdas or closures. There is actually a difference in definition between lambdas and closures
mathematically, and both of those can work as the other one depending on the use-case.
Lambdas are supposed to be functions that takes only one argument and has only one statement.
Closures are supposed to be functions that closes over the scope of its parent. Basically, closures can look for variables in the environment of its parent.
In Dart, there are no two entities separately known as lambdas and closures, instead there are closures. This is commonly seen in many programming languages, as they don't bother to keep a separation. By the way, the definition doesn't restrict a lambda from being a closure. And vice-versa.

Are there any drawbacks to using anonymous functions in JavaScript? E.g. memory use?

All JavaScript functions will behave in the same manner in that they inherit the variable environments in entire scope chain leading up to, and including, themselves. This is equally true for both anonymous and named functions.

This chain of references to the outer environments stays with each function, even if the function is passed into an entirely different scope.

Traditionally, this would mean that all variables in any given chain have a reference retained to them as long as the inner closure continues to exist. Although in modern browsers that compile the code, it is likely that there will be an analysis of which variables are actually referenced, and only those will be retained, allowing others that are no longer referenced to be garbage collected.

However, there are other situations where an anonymous function is wasteful.

Here's a common bit of code:

for( var i = 0; i < 100; i++ ) {
(function( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
})( i );
}

This is a situation where an anonymous function is a bit more wasteful than a named function because you're recreating an identical function 100 times during the loop when you could just reuse a named one.

function setConsole( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
}

for( var i = 0; i < 100; i++ ) {
setConsole( i );
}

This has the exact same closure overhead, but is more efficient because you've only constructed one function to create each new variable environment.

http://jsperf.com/immediate-vs-named (Thanks to @Felix Kling for the jsPerf.)

So with respect to the closure in particular, yes there's overhead as long as you maintain the closure by some permanent reference. I'd say that it is good to avoid this if possible but not to be obsessive about it. Sometimes a new variable environment added to the scope chain is simply the best solution.


EDIT: Here's an article from Google. Specifically, see Avoiding pitfalls with closures. for information on the performance impact of extending the scope chain, and for a claim that anonymous functions are “slower” than named functions.

anonymous function performance in PHP

I did some testing with array_map(), calling it with:

  1. The name of a function (array_map('test', $myArray);)
  2. A variable that contains a closure (array_map($test, $myArray);)
  3. A closure (array_map(function{}(), $myArray);)

In all three cases, the function was empty (function test(){})

The results for an array with 1.000.000 items ($myArray = range(1,1000000);)

Function: 0.693s
Variable:0.703s
Closure: 0.694s

For an array of 10.000.000 items, the results are this:

Function: 8.913s
Variable: 8.169s
Closure: 8.117s

So in neither case do we have much overhead, if any.

Also see the 4th comment on http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures
It comes to the same conclusions. In that comment, you also see that create_function() is significantly slower.

React performance: anonymous function vs named function vs method

The third option is best. You want to avoid setting state setState({}) inside your render function because it is no longer 'pure'. This is a term people use when talking about functional programming. It basically means there are no side-effects. Even though you aren't calling those functions with setState immediately in the render function, I think it's still best to pull that logic outside and get into the habit of thinking about pure functions.

Pure Functions
A pure function is a function which:
Given the same input, will always return the same output.
Produces no side effects.
Relies on no external mutable state.

Also considering performance, you are creating a new function every time the render function runs. You only need to create these functions once so it's best to pull them outside.

How often does the render function run? It can be quite a lot! Every time you change state or pass new props from parent component.

Anonymous functions and node.js performance

It really depends on your code, and without measuring it, you cannot know.
But in general, you can be quite sure that the time spent waiting for I/O significantly outweighs the time spent creating callback functions for handling these I/O events. Therefore, in normal scenarios there is probably no significant (or even no measurable) gain in optimizing the creation of callbacks. There are likely other areas where it is easier to gain performance and to find them you have to profile your code.

JQuery .each() : performance of anonymous function?

If you are concerned about performance, then you should not use .each(). It is much faster to iterate the contents of a collection with a for loop or a while loop and have no function call at all than it is to use .each() with its resulting function call for each item.

In answer to your question, the anonymous function will not be any slower than the named function. The differences are resolved at parse time before run-time.

This jsPerf shows a plain for loop as almost 10x faster than .each(): http://jsperf.com/each-vs-for-loop-mine.

Memory overhead of anonymous functions vs named functions when used as Jquery callbacks

By design, the observer pattern only keeps one instance of the observer. The event handler then calls this observer multiple times, with other instances of an event object, which holds the event parameters: which element fired the event, what is the context,... etc

So the handler is not duplicated, but referenced in each subject's 'listeners store'.

Note:
Kemal Dag also notes that anonymous functions by definition offer less performance then named function, I don't know if it is true, but if it is, the difference is negligible. Especially for a language as JavaScript, that uses anon functions so extensively, it can not afford a performance impact on it.



Related Topics



Leave a reply



Submit