I am pondering this:
function outer()
{
var myVar = 1;
function inner()
{
alert(myVar);
}
}
Now, as I understand it, this will result two lookups for the variable - one lookup to check the local variables in the inner function and one lookup for the outer function - at which point the variable is found.
The question is - will this be a particularly large drain on performance when compared to this:
function myFunc ()
{
var myVar = 1;
alert(myVar);
}
Which would only require the one lookup for the variable - it's then found as a local variable.
In older JS engines, scope lookups could cause some effects in performance.
However, even years back it was a very very minor difference - not really something you had to worry about.
Today's engines are most likely capable of optimizing lookups like this, and in general their performance is much much better. Unless you're writing something completely crazy or targeting a device with very poor performance, this is not something you need to worry about.
Related
If I am applying a function to a javascript array i.e.
var a = [1,2,3,4];
var x;
a.forEach(function(val) {
x = val + 1;
// do some stuff with x
});
Is it better to leave the variable declaration in the outer scope or to put the declaration inside the function? i.e.
var a = [1,2,3,4];
a.forEach(function(val) {
var x = val + 1;
// do some stuff with x
});
What I do not know is if the memory allocation for x is more expensive than the variable lookup process.
If you do not need the variable outside the forEach callback, put it inside. It is simply cleaner that way. Memory is not an issue.
Its better to put it into the loop. There is no performance difference. However using the scope the right way is a good starting point to detect errors:
var something = 5;
a.forEach(el => something = el);
console.log(something); // what is something? Why is it set?
What I do not know is if the memory allocation for x is more expensive than the variable lookup process
It depends. It depends on the exact code, the size of the array, how frequently the code is run, how many scopes there are between the code accessing the variable and the scope where the variable is declared, what optimizations the JavaScript engine on which the code is running does, etc.
So: Write the clearest, simplest code you can, and if you run into a performance problem related to that code, profile changes to see how to address it. Anything else is premature optimization and a waste of your time.
However: With the example given, if you declare it within the callback, x will be a local stack variable, and those are extremely cheap to allocate (in terms of execution time). I can't see that it would really matter either way (if you declare it outside, it's just one scope away), but it happens that in this case, the simplest, cleanest code (declaring it within the callback) is at least likely not to be worse than the alternative, and I'd say almost certainly better. But again: If it's an issue, profile the real code.
Practically, this change control two parameters: Scope and initiation.
Scope: if you need to use this var outside the loop, so you need to declare it out side, else you can drop it in and each iteration and the scope will declare, its probably saves memory outside the scope.
Initiation: in big programs the initiation can be critic time,
each time who the loop takes place you need to declare the var and its wasting time...
A powerful feature of Javascript is how you can use closures and higher order functions to hide private data:
function outerFunction(closureArgument) {
var closureVariable = something;
return function innerFunction() {
// do something with the closed variables
}
}
However, this means that every time I call outerFunction, a new innerFunction is declared and returned, which means that outerFunction(arg) !== outerFunction(arg). I wonder to what extent, if any, this might impact performance. As an example, a typical alternative would be to create a constructor that holds the data, and put innerFunction on the prototype:
function Constructor(argument) {
this.argument = argument;
this.variable = something;
}
Constructor.prototype.method = function() {
// do something with this.argument and this.variable
}
In that case, there is a single function that is shared by a number of instances, e.g new Constructor().method === new Constructor().method, but the data can not easily be made private, and the function can only be called as a method, so it has access to its context variables (This is just an example; there are other ways to solve the issue; my question is not actually about constructors and prototypes).
Does this matter from a performance perspective? It seems to me that since a function is always a literal, and the function body itself is immutable, Javascript engines should be able to optimize the above code example so that there shouldn't be a big performance impact because we have "multiple" functions instead of a single, shared function.
In summary: Does running the same function declaration multiple times come with any significant performance penalty, or do Javascript engines optimize it?
Yes, engines do optimise closures. A lot. There is no significant performance or memory penalty.
However, the prototype approach still can be faster, because engines are better at detecting the potential to inline a method call. You will want to step through the details in this article - though it could easily be outdated by newer compiler optimisations.
But don't fear closures because of that, any differences will be negligible for most cases you encounter. If in doubt, and with real need for speed, benchmark your code (and avoid premature optimisation till then). If closures make your code easier to read, write, maintain, go for them. They are a powerful tool that you don't want to miss.
I'm reading this article (http://javascript.info/tutorial/memory-leaks#memory-leak-size) about memory leaks which mentions this as a memory leak:
function f() {
var data = "Large piece of data";
function inner() {
return "Foo";
}
return inner;
}
JavaScript interpreter has no idea which variables may be required by
the inner function, so it keeps everything. In every outer
LexicalEnvironment. I hope, newer interpreters try to optimize it, but
not sure about their success.
The article suggests we need to manually set data = null before we return the inner function.
Does this hold true today? Or is this article outdated? (If it's outdated, can someone point me to a resource about current pitfalls)
Modern engines would not maintain unused variables in the outer scope.
Therefore, it doesn't matter if you set data = null before returning the inner function, because the inner function does not depend on ("close over") data.
If the inner function did depend on data--perhaps it returns it--then setting data = null is certainly not what you want to, because then, well, it would be null instead of having its original value!
Assuming the inner function does depend on data, then yes, as long as inner is being pointed to (referred to by) something, then the value of data will have to be kept around. But, that's what you are saying you want! How can you have something available without having it be available?
Remember that at some point the variable which holds the return value of f() will itself go out of scope. At that point, at least until f() is called again, data will be garbage collected.
The general rule is that you don't need to worry about memory and leaks with JavaScript. That's the whole point of GC. The garbage collector does an excellent job of identifying what is needed and what is not needed, and keeping the former and garbage collecting the latter.
You may want to consider the following example:
function foo() {
var x = 1;
return function() { debugger; return 1; };
}
function bar() {
var x = 1;
return function() { debugger; return x; };
}
foo()();
bar()();
And examine its execution in Chrome devtools variable window. When the debugger stops in the inner function of foo, note that x is not present as a local variable or as a closure. For all practical purposes, it does not exist.
When the debugger stops in the inner function of bar, we see the variable x, because it had to be preserved so as to be accessible in order to be returned.
Does this hold true today? Or is this article outdated?
No, it doesn't, and yes, it is. The article is four years old, which is a lifetime in the web world. I have no way to know if jQuery still is subject to leaks, but I'd be surprised if it were, and if so, there's an easy enough way to avoid them--don't use jQuery. The leaks the article's author mentions related to DOM loops and event handlers are not present in modern browsers, by which I mean IE10 (more likely IE9) and above. I'd suggest finding a more up-to-date reference if you really want to understand about memory leaks. Actually, I'd suggest you mainly stop worrying about memory leaks. They occur only in very specialized situations. It's hard to find much on the topic on the web these days for that precise reason. Here's one article I found: http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html.
Just in addition to to #torazaburo's excellent answer, it is worth pointing out that the examples in that tutorial are not leaks. A leak what happens when a program deletes a reference to something but does not release the memory it consumes.
The last time I remember that JS developers had to really worry about genuine leaks was when Internet Explorer (6 and 7 I think) used separate memory management for the DOM and for JS. Because of this, it was possible to bind an onclick event to a button, destroy the button, and still have the event handler stranded in memory -- forever (or until the browser crashed or was closed by the user). You couldn't trigger the handler or release it after the fact. It just sat on the stack, taking up room. So if you had a long-lived webapp or a webpage that created and destroyed a lot of DOM elements, you had to be super diligent to always unbind events before destroying them.
I've also run into a few annoying leaks in iOS but these were all bugs and were (eventually) patched by Apple.
That said, a good developer needs to keep resource management in mind when writing code. Consider these two constructors:
function F() {
var data = "One megabyte of data";
this.inner = new function () {
return data;
}
}
var G = function () {};
G.prototype.data = "One megabyte of data";
G.prototype.inner = function () {
return this.data;
};
If you were to create a thousand instances of F, the browser would have to allocate an extra gigabyte of memory for all those copies of the huge string. And every time you deleted an instance, you might get some onscreen jankiness when the GC eventually recovered that ram. On the other hand, if you made a thousand instances of G, the huge string would be created once and reused by every instance. That is a huge performance boost.
But the advantage of F is that the huge string is essentially private. No other code outside of the constructor would be able to access that string directly. Because of that, each instance of F could mutate that string as much as it wanted and you'd never have to worry about causing problems for other instances.
On the other hand, the huge string in G is out there for anyone to change. Other instances could change it, and any code that shares the same scope as G could too.
So in this case, there is a trade-off between resource use and security.
Before asking my question, let me give a disclaimer. I know what var does, I know about block scope, and I know about variable hoisting. I'm not looking for answers on those topics.
I'm simply wondering if there is a functional, memory, or performance cost to using a variable declaration on the same variable more than once within a function.
Here is an example:
function foo() {
var i = 0;
while (i++ < 10) {
var j = i * i;
}
}
The previous could just have easily been written with the j variabled declared at the top:
function foo() {
var i = 0, j;
while (i++ < 10) {
j = i * i;
}
}
I'm wondering if there is any actual difference between these two methods. In other words, does the var keyword do anything other than establish scope?
Reasons I've heard to prefer the second method:
The first method gives the appearance of block scope when it's
actually function scoped.
Variable declarations are hoisted to
the top of the scope, so that's where they should be defined.
I consider these reasons to be good but primarily stylistic. Are there other reasons that have more to do with functionality, memory allocation, performance, etc.?
In JavaScript - The Good Parts Douglas Crockford suggests that by using the second method and declaring your variables at the top of their scope you will more easily avoid scope bugs.
These are often caused by for loops, and can be extremely difficult to track down, as no errors will be raised. For example;
function() {
for ( var i = 0; i < 10; i++ ) {
// do something 10 times
for ( var i = 0; i < 5; i++ ) {
// do something 5 times
}
}
}
When the variables are hoisted we end up with only one i. And thus the second loop overwrites the value, giving us an endless loop.
You can also get some bizarre results when dealing with function hoisting. Take this example:
(function() {
var condition = true;
if(condition) {
function f() { console.log('A'); };
} else {
function f() { console.log('B'); };
}
f(); // will print 'B'
})();
This is because function bodies are hoisted and the second function overwrites the first.
Because searching for bugs like this is hard and regardless of any performance issues (I rarely care about a couple of microseconds), I always declare my variables at the top of the scope.
There will not be any differences during execution time. There might be a imperceptibly small difference in interpretation/compilation time, but that of course will be implementation dependent. There also might be a few bytes different in the size of the file, which could also affect download time. I don't think either of these are worth being bothered about.
As you already know, any variable declaration will be hoisted to the top of the function. The important thing to note is that this occurs during the interpretation/compilation process, not during execution.
Before a function is executed, the function must be parsed. After each function is parsed, they will both have all of the variable declarations moved to the top, which means that they will be identical and there will be no execution time cost incurred.
For the same reason, there are no memory cost differences. After parsing, there will be no differences at all.
Since you are not asking about style I am not telling you which I think is better. But I will say that the only reason you should prefer one over the other is style.
Style
Subjective. I prefer the approach that keeps the var close to the usage site, but I always keep the scoping rules in mind. I also avoid combining multiple declarations into a single var and prefer multiple var statements.
Memory allocations
Variables are not objects: not applicable. Due to the hoisting rules, the variable "slot" has the same lifetime in all cases.
Performance
No. There should be no difference in terms of performance. While an implementation could technically really mess this up - they don't.
The only way to answer this (besides looking at every implementation in minutia) is to use a benchmark.
Result: noise differences on modern browsers
The 2nd way saves the 4 characters in the the javascript file - but in terms of the actual code generation or execution speed I don't believe there is any difference at all.
Your example will function exactly the same. It could be even more unclear than your example to use 'var' in a block, though. Say, for example you want to update a variable that is outside of the scope (by not using 'var') conditionally, or use a local 'var' instead. Even if that condition is false, 'j' becomes local. It turns out not to be as trivial as it appears to do that.
var j = 1;
function foo () {
j = 2;
if (false) {
var j = 3; // makes `j = 2` local simply for being in the same function
}
console.log(j);
}
foo(); // outputs 2
console.log(j); // outputs 1
That's one tricky case that may not work as you expect just by looking at the code.
There are no downsides to declaring every 'var' on top, only up-sides.
I have seen Javascript code that claims to speed up function call overhead like:
function foo() {
// do something
}
function myFunc() {
var fastFoo = foo; // this caches function foo locally for faster lookups
for (var i = 0; i < 1000; i++) {
fastFoo();
}
}
I do not see how this can speed up javascript function call overhead, as it seems to me like it is just a memory lookup, either at the top of the current stack (for fastFoo) or somewhere else in the stack (I am not sure where the global context is stored... anyone?).
Is this a relic of ancient browsers, a complete myth, or a true improvement enhancer?
It is all dependent on scope. Accessing the local scope is always faster than accessing a parent scope. if the function is defined in the parent scope you will often see speedups if you make a local reference.
If this speedup is significant depends on many things, and only testing in your case will show if it is worth doing so.
The difference in speed depends on the difference of scope.
Calling a.b.c.d.e.f.g.h(); from the scope of x.y.z is slower than calling a.b(); from the scope of a.b.c (not the prettiest or most correct examples, but it should ´serve it's purpose :)
This will result in an infinitesimal performance gain.
Don't do it.