Does any one know about optimization effects of passing in a variable via function arguments versus having the variable available via a closure? It seems like passing in variables via function arguments would be faster since objects are copied by reference (so fast copy time) and climbing the scope environments of the function requires checking the environment at each level. Here's the gist of what I mean
a = 5;
b = function() {
alert(a);
}
b();
versus
a = 5;
b = function(c) {
alert(c);
}
b(a);
Which in theory performs faster?
I had the same question a little while ago, so I slapped together a quick'n'dirty benchmark. It appears that most popular browsers (surprisingly) prefer looking up in the scope (FF24 very much so).
I hope this answers your question.
climbing the scope environments of the function requires checking the environment at each level
Only theoretically. In fact, since the scope chain is not dynamic, this can and will be optimized to a static reference.
passing in variables via function arguments would be faster since objects are copied by reference (so fast copy time)
Even it is very fast, they still need to be copied. The function needs to allocate extra memory for them, while the reference to the closure does not anything like that.
If you can put a value in the closure scope, do it. It's only practical, you want to build a closure. If you don't want and need variable arguments in your function, use parameters. Use the more readable alternative.
It all depends. Don't worry about it unless it's a big issue in the future.
Related
Lately, I was studying Scope in Javascript. I want to know whether automatically hoisting is done at compile time or at the time of executing the code(run time). If it does at run time then I have another question does auto-hoisting will slow down the performance of the Javascript program.
something = a();
function a(){
console.log("hoisting");
return 10;
}
var something;
Should we use manual hoisting or it would be better to use automatically hoisting?
To put my comments as an answer:
People have a different understanding of what hoisting supposed to mean. Fact is that, according to the spec, every time a function is called a new execution context is created, which holds a new environment. Then the function body is processed to find all variable declarations (var, let, const (and function declarations)) and bindings for those names are created in the new environment. var declarations are initialized with undefined. Then the body is actually evaluated.
Considering this, from the perspective of the engine it doesn't really matter where you place the var declaration, the whole body has to be processed anyway.
Having said that, I would be surprised if actual implementations didn't cache that information. After all, the variable declarations in a function don't change between function calls.
As I know, There are no performance issues. The initializations are getting done in compile time. So doesn't matter you initialize on top or bottom, The JS engine will create the references in compile time.
BUT
If you forgot to initialize at the bottom, It will be initialized as undefined by default. Because of hoisting it’s considered a practice to declare functions or variables at the top of their respective scopes.
JavaScript: What is Hoisting? (Recommended)
It is not done at run time.
It's in the compile process.
So it doesn't slow down the performance.
Just before the code is executed the compiler scans for all variable and function declarations and allocates them in the memory.
Imagine I have a function that is being called very often and needs to use a variable internally.
function busyFunction() {
var intermediateResult;
/* compute something */
return something;
}
As I understand, in this first example the browser will allocate memory for the variable and then schedule it for garbage collection at some point.
var intermediateResult;
function busyFunction() {
/* compute something */
return something;
}
I know the second example will pollute the scope outside of busyFunction. But since the the memory for the variable would not be garbage collected until the parent function is, would this be beneficial for performance? If I'm wrong here or if the effect is negligible, I'd rather use the first cleaner example.
Declaring variables in a higher scope makes them a bit slower to access (very so in the global scope), and - more importantly - harder to optimise for the compiler. The garbage collection cost is negligible. I will expect this to actually be slower. The difference should be quite small (hardly measurable), but as always, benchmark it yourself on your actual code with real data.
The only case where the performance would improve is if you want to persist a value between the invocations, and would gain your advantage by not repeatedly running costly initialisation code. Especially if you can make the variable a constant initialised before the function is called.
In general, aim for readable and idiomatic code, optimising compilers do as well.
In short, yes. You consume less resources, because every time the function gets executed you don't create a variable in it's scope that then gets thrown away after the function execution ends. Personally I'd advise to create an object which holds both the variable and the function so that the variable doesn't just "float around", but that's detail.
Another thing however is code readability. I presume the example in the question is a simplified version of what you're dealing with. Here it basically comes down to balance between readability and efficiency. If you think it would be confusing to leave it outside then leave it in the function unless the advantages of having it outside heavily outweigh the fact that the code is less confusing.
Unless the performance improvement is very significant I'd advise to leave it in the function for clarity.
I am referencing a answer from stack overflow -->>
V8 uses a heap similar to JVM and most other languages. This, however, means that local variables (as a general rule) are put on the stack and objects in the heap. This may for instance not hold if a function closes over these values. As in the JVM, primitives can only be stored on the stack if they are stored in a local variable.
As a user it is not something you would normally need to worry about.
(V8 developer here.) You are correct, local variables in one function that another function closes over can't easily be stored on the stack. Specifically, in V8 they are stored in a so-called "Context" object on the heap, which is what #JonasWilms is referring to. To illustrate with an example:
function outer() {
let a = 1; // Will be on the stack
let b = 2; // Will be in the context on the heap
return function inner() {
return b;
}
}
You are also absolutely correct that this is not something you need to worry about :-)
In particular, because "stack" and "heap" really are internal implementation details; they just so happen to be the most common way how engines (for many languages) achieve the required behavior with decent performance.
More conceptually speaking, we're talking about scopes and lifetimes of variables here: in the example, a goes out of scope (=becomes unreachable) when outer finishes running, whereas b is still reachable via inner, so it lives on as long as inner could be called again. How an engine accomplishes that is an internal detail and could change at any time. For example, an engine could decide to simplify its implementation by always putting all variables on the heap, avoiding the need to analyze in advance which variables will be closed over and which won't. All that matters is the observable behavior, not how it's achieved under the hood.
If you look at the v8 doc, you can see that Functions do have a Local<Context> attribute. Local is a wrapper class for values managed by the garbagge collector, so yes, the Context resides on the heap.
I'm not too familiar with JavaScript's mechanics of scope resolution.
I was wondering, how expensive is it for JavaScript to access variables that are one or two scopes "upwards" in the scope chain?
Say I have a function named scope3 that is inside a function named scope2 which is inside a function named scope1.
If I try to access a variable defined in scope1 from scope3, does JavaScript have to load all variables in all three scopes in order to find it? If so, the expensiveness of such operation depends on how many variables are defined in each scope, correct?
The doubt arose because I have multiple functions that make use of the same elements or values. Values that require a function call to be calculated.
So, I was wondering if it is more efficient to retrieve the elements and re-calculate the values in each function, to avoid climbing the scope chain, or if it is best to wrap the functions inside an outer scope, retrieve the elements / calculate the values only once, and then simply access them from the inner functions.
This, of course, is a semplified example of my structure. In reality I have multiple scoping levels.
What is best-practice for cases like this?
Thank you.
I create a small jsperf test to have an idea.
v8 (chromium) is super fast when there is no closure, but a lot slower with closure. How 'far' it has to reach to get the variable is not relevant.
Spidermonkey (firefox) is slower (50% of chrome max speed) but the speed is consistent.
So as a first approximation, you can consider closures to be slower. The number of nesting level has no impact on speed though.
You could pass the variable as parameter (if possible in your code), it's not expensive and it's cleaner.
So this is puzzling to me. Are variables expensive?
Let's take a look at this code:
var div1 = document.createElement('div');
var div2 = document.createElement('div');
div2.appendChild(div1);
Now this one
var div2 = document.createElement('div');
div2.appendChild(document.createElement('div'));
So, on the second example, I'm doing the same thing as on the first one. Is it more expensive to declare a variable than not? Do I save memory by just creating and using an element on the fly?
EDIT: this is a sample code to illustrate the question. I know that in this specific case, the memory saved (or not) in minimal.
Variables are extremely cheap in JavaScript, yet, no matter how cheap they are, everything has a cost.
Having said that, it's not a noticable difference, and you should be thinking more about making your code readable rather than performing micro-optimizations.
You should be using variables to save repeated operations. In your example above, it's likely you need the variable pointing to the newly created div, or you'll be able to do nothing to it... unless you end up retrieving it from the DOM; which will prove many times more costly than the variable, as DOM manipulation is one of the slowest parts of JavaScript.
In theory, there is a tiny little amount of memory you save by not doing the variable declaration, because a variable declaration requires that the JavaScript engine creates a property on the variable binding object for the execution context in which you declare it. (See the specification, Section 10.5 and associated sections.)
In reality, you will never notice the difference, not even on a (relatively) slow engine like IE's. Feel free to use variables wherever they make the code clearer. Creating a property on a variable binding object (e.g., declaring a variable) is a very, very, very quick operation. (Avoid it at global scope, of course, but not because of memory use.)
Caveat: If the variable refers to a big memory structure that you only hold temporarily, and you create closures within that function context, the big memory structure may (in some engines) be kept in memory longer than necesary. Example:
function foo(element) {
var a = /* ...create REALLY BIG structure here */;
element.addEventListener("event", function() {
// Do something **not** referencing `a` and not doing an `eval`
}, false);
}
In an unsophisticated engine, since the event handler is a closure over the context of the call to foo, in theory a is available to the handler and so what it references remains "referencible" and not available for garbage collection until/unless that event handler function is no longer referencible. In any decent engine (like the V8 engine in Chrome), because you neither refer to a nor use eval within the closure (event handler), it's fine. If you want to defend yourself from mediocre engines, set a to undefined before foo returns, so the engine (no matter how mediocre) knows that the event handler won't be referencing that structure even if it were to reference a.
Yes, you save memory, no it is in no way an amount that matters.