i++ vs. ++i in a JavaScript for loop - javascript

Because of JSLint, I almost always use i += 1 to increment a JavaScript for loop, but for quick and dirty scripts, I use i++ instead.
However, I see a lot of for loops in other people's code in which they increment i by doing ++i instead.
As far as I know, there is no difference in meaning between i++ and ++i, and jsPref shows no difference in performance.
As such, I'm wondering where the convention of doing ++i comes from and why people tend to do it.
Does anyone know why a lot of JS coders tend to prefer ++i over i++ when incrementing the counter in a for loop?
Thanks.

The difference is that i++ returns the value of i before incrementing and ++i the value of i after incrementing. There is no difference if you ignore the return value, e.g. in:
for (var i = 0; i < 10; i++) {
}
The habit of using ++i over i++ comes from C, where people were worried that storing the old value for i in i++ would incur a performance penalty.

Way back in the day (we're talking IE6/7 here!), I recall benchmarking both forms and found that there was a small performance improvement with ++i instead of i++. My (unproven) theory was that a non-optimizing JS engine had to do a tiny bit more work in the i++ case: it had to save the previous value in case it would be used - and being a non-optimizing engine it didn't realize that the value would in fact not be used and didn't need to be saved.
However, with modern browsers there is no significant difference. If anything, i++ seems to be a tiny bit faster in many browsers.
Here are some tests of a variety of different loops:
http://jsperf.com/mikes-loops/5
Look for the results for "Traditional Loop" (this uses ++i) and "Traditional Loop with i++".
Regarding JSLint's requirement that one should never use ++i or i++ but only use i += 1 instead, that is simply insane and over-controlling, like so many other things in JSLint.
Personally I recommend JSHint instead. It is less dogmatic, much more practical, and easier to customize to your own style.

In JS and PHP it does not make any difference, I think even in Java it does not make any difference but in pure c when compiler is not optimizing code it does, and that is why a lot of people use ++i because they are used to it from c.
EDIT:
This is an answer for JS if you want history of pre and post increment searc C/C++ pre/post increment. Or see comments on #Orvev's answer.

There is a difference, however not when used in a for loop.
In an expression, i++ evaluates to the previous value of i, and then i is incremented. ++i increments first, and evaluates then.
For this reason, some programmers prefer to write ++i in their for-loops — either because they're used to it, or because they feel it is "more right" somehow.
edit: More probable is the solution Overv proposed: a relict from C.

Related

declaring for-loop variable best practice

My question is more a curiosity question on for-loop style.
While reading some old code by others, I encountered a style I haven't seen before.
var declaredEarlier = Array
for(var i=0, length=declaredEarlier.length; i < length; i++) {
//stuff
}
I had never seen declaring a length before use and since this is an old app, was this kind of style a C/C++/old Java carryover? or was this developer unique?
Is there any benefit for declaring length that way instead of doing what I normally do:
for(var i=0; i < declaredEarlier.length; i++) {
//stuff
}
If this has been asked before, I could not find it. And if it's not stackoverflow applicable, which forum would be better to ask?
There are two reasons you might grab the length up-front like that:
In case the length may change (remember, JavaScript arrays aren't really arrays* and their length is not fixed) and you want to use the original length to limit the loop, or
To avoid repeatedly looking up the length on the object, since you know it's not going to change
The first is obviously substantive; the second is style and/or micro-optimisation.
* Disclosure: That's a link to a post on my anemic little blog.
for the first style the value of declaredEarlier can change so you need to use it
like that length=declaredEarlier.length
but for the second style you already know the value you dont need to calculate it again

Javascript For-Loop Condition Caching

I've put together a jsperf test that compares for loops that iterate over an array with caching the array length condition vs not caching. I thought that caching the variable before to avoid recalculating the array length each iteration would be faster, but the jsperf test says otherwise. Can someone explain why this is? I also thought that including the array length variable definition (when cached) within the for loop's initialization would reduce the time since the parse doesn't need to look up the "var" keyword twice, but that also doesn't appear to be the case.
example without caching:
for(var i = 0; i < testArray.length; i++){
//
}
example with caching
var len = testArray.length;
for(var i = 0; i < len; i++){
//
}
example with caching variable defined in for loop initialization
for(var i = 0, len=testArray.length; i < len; i++){
//
}
http://jsperf.com/for-loop-condition-caching
Can someone explain why this is?
This optimization and case is extremely common so modern JavaScript engines will automatically perform this optimization for you.
Some notes:
This is not the case when iterating a NodeList (such as the result of querySelectorAll
This is an overkill micro optimization for most code paths anyway, usually the body of the loop takes more time than this comparison anyway.
The performance of the scenarios that you posted depends on how smart the JS engine's optimizer is. An engine with a very dump optimizer (or no optimizer at all) will likely be faster when you are using the variable, but you can't even rely on that. After all, length's type is well-known, while a variable can be anything and may require additional checks.
Given a perfect optimizer, all three examples should have the same performance. And as your examples are pretty simple, modern engines should reach that point soon.

Is the following considered micro optimization

I am not very well parsed in javascript, but do you call the following micro optimization?
for(var j=0;j < document.getElementsByTagName('a').length; j++)
{
//...
}
var Elements = document.getElementsByTagName('a');
var ElementsLength = Elements.length;
for(var j=0;j < ElementsLength ; j++)
{
//...
}
var Elements = document.getElementsByTagName('a');
for(var j=0;j < Elements.length; j++)
{
//...
}
does document.getElementByTagName really get called in every loop
cycle in the first case?
do browsers try to optimize the javascript we write?
is there any difference between the second and third case considering
that the collection will never change?
does document.getElementByTagName really get called in every loop cycle in the first case?
Yes.
do browsers try to optimize the javascript we write?
It won't change it functionally. There's a difference between calling a function once and calling it every time in a loop; perhaps you meant to call the function every time. "Optimising" that away is actually changing what the program does.
is there any difference between the second and third case considering that the collection will never change?
Not functionally, but performance wise yes. Accessing the length attribute is a little more overhead than reading the number from a simple variable. Probably not so much you'd really notice, but it's there. It's also a case that cannot be optimised away, since Elements.length may change on each iteration, which would make the program behave differently. A good optimiser may be able to detect whether the attribute is ever changing and optimise in case it's certain it won't; but I don't know how many implementations really do that, because this can become quite complex.

Javascript Optimization: Looping and handling different ways in different browsers

In my quest to optimize my game engine I have discovered optimization i have been doing affecting each browser differently, in a lot of cases making one browser worse and the other better!
Currently I'm trying to optimize looping as i do alot of it and depending on the way this is done can have a big effect on the performance of my engine.
Based on the results here http://jsperf.com/for-vs-while-loop-iterating/3
It seems a reverse for loop in chrome is the fastest
var l = foo.length;
for (var i = l; i--;) {
}
And in firefox a forward for loop is fastest
var l = foo.length;
for (var i = 0; i < l; i++) {
}
Now in order to use the correct one per browser I'm doing something like this
function foreach(func, iterations){
var browser = $.browser;
var i;
if (browser.webkit)
{
for(i=iterations;i--;)
{
func(i);
}
}
else
{
for (i = 0; i < iterations; i++)
{
func(i);
}
}
}
but it seems there may be alot of overhead here that may hurt performance.
If you were to provide different ways of looping for different browsers what would you do?
EDIT: seems there was a bug in my testing where i was doing one too many loops on the forward loop and now chrome seems to be the fastest there also, I may not need to optimize the loops but it may still be worth while as mention in another comment incase browser versions change performance again
Unfortunately, if your goal is the best performance loop on each browser, the very last thing you want to do is introduce function calls into it. There's no way you can define your foreach function such that it will be anything like as fast as the straight for loop. Calling the iteration function will wash out any gains you might get.
A quick jsperf can confirm this easily enough. For instance, run this one on Chrome or a recent version of Firefox or Opera. It compares looping forward with for, backward with for, or using the browser's built-in Array#forEach function (part of ECMAScript5). (I think we can assume any foreach function you build will be slower than the built-in one.) As you can see, the forEach version is dramatically slower than either of the for loops, which makes sense: Calling functions isn't very expensive, but it isn't free.
Mind you, what you're doing in the loop probably washes out the difference between counting up and count down. What I'd do is figure out what's fastest on the slower browsers, and use that. You said, for instance, that a reverse loop is faster in Chrome but a forward loop is faster in Firefox. As Chrome's V8 is dramatically faster than Firefox's SpiderMonkey (at the moment, these things are constantly in flux), pick the forward loop, as it's faster on the slower engine.
Otherwise, you're into needing to do preprocessing on your code and churning out a different version tailored to each browser.
I don't think your overhad is as big as you feel, but what you can do is do your test only once:
var foreach;
if (forwardIsFaster) {
foreach = function (func, iterations) {
// loop forwards...
};
} else {
foreach = function (func, iterations) {
// loop backwards...
};
}
That said, I'm not sure using browser sniffing is the best solution here; maybe instead do a test loop on startup, measure which solution is faster, and choose the one that turns out to be faster.
When you start doing something significant inside the loop (e.g. just printing the variable), the order of iteration doesn't matter, see:
http://jsperf.com/for-vs-while-loop-iterating/4
So stop caring about this and if (and only if) your code is slow in any place, just profile it and optimize that part.
You could make foreach return a function, which would be an iterator. So you would have, once in your script, var iterator = foreach($.browser.webkit);. From then on, you would just use iterator(iterations, callback), which would no longer be executing any conditionals.
The key, basically, is that the user's browser won't change, so the result of the execution of that conditional needs to be evaluated only once per script.

Other ways to increment a variable in JavaScript [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why avoid increment (“++”) and decrement (“--”) operators in JavaScript?
I'm a big fan of Douglas Crockford and his excellent book, JavaScript: The Good Parts. I also use his JSLint tool on an hourly basis before checking in any code to our repository, as is good sense.
One thing I've noticed when running code through JSLint is its insistence that the ++ increment operator is somehow evil. I know I can turn certain rules off, but that's cheating ;). Crockford mentions his dislike on page 112 of JS: TGP...
In my own practice, I observed that when I used ++ and --, my code tended to be too tight, too tricky, too cryptic. So, as a matter of discipline, I don't use them any more. I think that as a result, my coding style has become cleaner.
That's all very lovely, but he doesn't give any examples of the way he codes them now. I assume he's doing something like...
var i;
i = 0;
i = i + 1;
Again, great, but I've got a few basic 'for loops' in my JS code, as I imagine many people have, and I've always used the standard syntax...
for (i = 0; i < myArray.length; i++) {
// Loop Stuff
}
Am I missing something? What's the cleanest and/or best way to increment/decrement?
I think this is rather controversial, and I personally stick to i++ in loops. Of cource, you can replace it with i = i + 1 in your loop statement, to be fully compliant to JSLint.
There aren't real alternatives to increment and decrement numerical values in JavaScript. You can often use Array.forEach() and/or Object.keys() in order to prevent numerical indexes.
The only tricky thing I see in autoincrement/decrement operators (and I'm quite surprised that no one here pointed that out) is the difference between prefix (++i) and postfix (i++) versions. I also believe that autoincrement/decrement operators are slightly more efficient, in general. Besides this, I think the choice is based mainly on aesthetics, especially in javascript.
to pass JSLint I now always do:
for (var i = 0; i < myArray.length; i+=1) {
// Loop Stuff
}
In C/C++ this is important, especially with arbitrary iterators and pre/post increment semantics. Also, random access vs forward-iterators.
In Javascript it's more about aesthetics than anything else. Unless you're dealing with strings. "1"+1 is "11".
I would say that ++i is an idiom that's worth being consistent with.
JSLint is wrong.
Personally, I see nothing wrong with the ++/-- operators for incrementing and decrementing. While something like i = i + 1; may be easier for new coders, the practice is not rocket science once you know what the operators stand for.
Regarding loop, one original idea can be using such loop to avoid all kinds of numbers:
var a = [];
for (var i in " ")
a.push("Loop iteration here");
alert(a.join("\n"));
Meaning iterate over a string, there will be amount of iterations equal to the string length - 5 in the above example.
Live test case: http://jsfiddle.net/vTFDP/

Categories