views:

1193

answers:

5

I was browsing Google Code when I chanced upon this project called JSpeed - optimization for Javascript.

I noticed one of the optimization was to change i++ to ++i in for loop statements.

Before Optimization

for (i=0;i<1;i++) {}

for (var i = 0, j = 0; i < 1000000; i++, j++) {
    if (i == 4) {
        var tmp = i / 2;
    }

    if ((i % 2) == 0) {
        var tmp = i / 2;
        i++;
    }
}
var arr = new Array(1000000);
for (i = 0; i < arr.length; i++) {}

After optimization

for(var i=0;i<1;++i){}
for(var i=0,j=0;i<1000000;++i,++j){if(i==4){var tmp=i>>1;}
if((i&1)==0){var tmp=i>>1;i++;}}
var arr=new Array(1000000);for(var i=0,arr_len=arr.length;i<arr_len;++i){}

I know what pre and post increments do, but any idea how does this speeds the code up?

+1  A: 

The optimization isn't the pre versus post increment. It's the use of bitwise 'shift' and 'and' operators rather than divide and mod.

There is also the optimization of minifying the javascript to decrease the total size (but this is not a runtime optimization).

Taylor Leese
There is some evidence that pre vs. post does make a difference...depending on the engine.
Glenn
Can you provide a source? That doesn't make much sense to me.
Taylor Leese
i know there are other optimizations as well. but if this is not considered part of optimization then why does JSpeed bother including this changing post to pre increment?
thephpdeveloper
@Taylor: see the link in my answer.
Glenn
The link doesn't reference anything about pre vs. post increment.
Taylor Leese
Yeah. My mistake. Ignore most of what I've said. I have foggy memories of reading some tests where it _did_ make a difference.
Glenn
+1  A: 

Sounds like premature optimization. When you're nearly done your app, check where the bottlenecks are and optimize those as needed. But if you want a thorough guide to loop performance, check this out:

http://blogs.sun.com/greimer/entry/best_way_to_code_a

But you never know when this will become obsolete because of JS engine improvements and variations between browsers. Best choice is to not worry about it until it's a problem. Make your code clear to read.

Edit: According to this guy the pre vs. post is statistically insignificant. (with pre possibly being worse)

Glenn
it's more of the increment part rather than the way to access arrays. i know how `for(i=0;i<arr.length;i++)` can slow down the code (each iteration calls arr.length) - but not how pre and post increment
thephpdeveloper
I don't see anything in your link that discusses pre vs post increment.
Taylor Leese
Ha! I'm blind. There's no pre vs post in my link. Checking for a proper reference now.
Glenn
@Glenn awesome. =D
thephpdeveloper
+2  A: 

This is what I read and could answer your question: "preincrement (++i) adds one to the value of i, then returns i; in contrast, i++ returns i then adds one to it, which in theory results in the creation of a temporary variable storing the value of i before the increment operation was applied".

KooiInc
possible theory. any citations or links to read up more?
thephpdeveloper
It came from: http://physical-thought.blogspot.com/2008/11/pre-vs-post-increment-speed-test.html. As I understand, the practice may be different per compiler. By the way: via http://home.earthlink.net/~kendrasg/info/js_opt/ you may learn more about javascript optimization.
KooiInc
Hi Kooilnc - yep saw that blog post by googling. thanks a lot.
thephpdeveloper
A: 

Just tested it in firebug and found no difference between post- and preincrements. Maybe this optimization other platforms? Here is my code for firebug testing:

function test_post() {
    console.time('postIncrement');
    var i = 1000000, x = 0;
    do x++; while(i--);
    console.timeEnd('postIncrement');
}

function test_pre() {
    console.time('preIncrement');
    var i = 1000000, x = 0;
    do ++x; while(i--);
    console.timeEnd('preIncrement');
}

test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();
test_post();
test_pre();

Output is:

postIncrement: 140ms
preIncrement: 160ms
postIncrement: 136ms
preIncrement: 157ms
postIncrement: 148ms
preIncrement: 137ms
postIncrement: 136ms
preIncrement: 148ms
Anatoliy
i've already done the test on firefox. doesn't have much diff as well. theory given on the other answer might be just the answer. thanks for the effort!
thephpdeveloper
Who cares speed wise. Unless you JavaScript is doing zillions it's nit going to be noticable by the end user.
mP
@mP - agreed. but some browsers *coughIE*... =D
thephpdeveloper
+2  A: 

This is a faux optimization. You're saving like 1 op code. If you're looking to optimize your code with this technique, then you've gone the wrong way. Also, most compilers/interpreters will optimize this for you anyway (reference 1). In short I wouldn't worry about. But, if you're really worried, you should use i+=1.

Here's the quick-and-dirty benchmark I just did

var MAX = 1000000, t=0,i=0;

t = (new Date()).getTime();
for ( i=0; i<MAX;i++ ) {}
t = (new Date()).getTime() - t;

console.log(t);

t = (new Date()).getTime();
for ( i=0; i<MAX;++i ) {}
t = (new Date()).getTime() - t;

console.log(t);

t = (new Date()).getTime();
for ( i=0; i<MAX;i+=1 ) {}
t = (new Date()).getTime() - t;

console.log(t);

Raw results

Post    Pre     +=
1071    1073 1060
1065    1048 1051
1070    1065 1060
1090    1070 1060
1070    1063 1068
1066    1060 1064
1053    1063 1054

Removed lowest and highest

Post    Pre     +=
1071    ---- 1060
1065    ---- ----
1070    1065 1060
----    1070 1060
1070    1063 ----
1066    1060 1064
----    1063 1054

Averages

1068.4  1064.2 1059.6

Notice that this is over one million iterations and the results are within 9 milliseconds on average. Not really much of an optimization considering that most iterative processing in JavaScript is done over much smaller sets (DOM containers for example).

Justin Johnson
agreed justin. 15char
thephpdeveloper
what do you mean by 15char?
Justin Johnson
to fill up the 15 characters minimum. anyway, 1 op * n iterations can be a lot.
thephpdeveloper
My point was that the difference is negligible and can't really be differentiated in smaller datasets (<1000), which is more common in JavaScript than larger data sets. Typically, datasets that are iterated over in JavaScript are DOM collections, which are typically under 200 members. Even still, the bottle neck in these situations is the DOM, not the minimal optimization of pre vs post vs +=
Justin Johnson