Comparing JavaScript loops performance (for, do while, for in)

update:The Chrome results where so strange that I retook the tests again with more samples and averaged the results. Things look more reasonable now.

I always try to optimise code for the fastest speed possible. While playing with some javascript (the culprit is this marvelous game by @tonyvirtual called Chain Reaction) I started thinking about the different speed gains that one might get from using different kinds of loops. A basic for loop in javascript can be implemented in many ways but typical are these 3:

// Loop 1
for (var i=0; i < Things.length; i++) {
    // Do something with Things[i]
};
 
// Loop 2
var i = Things.length-1;
do {
// Do something with Things[i]
} while (i--);
 
// Loop 3
for (var i in Things){
// Do something with Things[i]
}

Your Javascript results

Previous Results with other browsers

There are many online reports that favour one of the loops instead of the others, but I wasn’t convinced so I decided to test them myself. I devised a simple test that you can run in your browser or you can modified it by getting it from github.com and tested the script in 3 different browsers all on the Mac OS X 10.5.8. The browsers are Firefox 10.0.2, Safari 5.0.6 and Chrome 19.0.1049.3 dev so I don’t know if these will apply to other browsers or OSes (use the github file).

The JavaScript performance results are listed below in the format min (average 10x):

Firefox

Loop 1 (for ;;) — 117 (118.5)
Loop 2 (do – while) — 119 (125.9)
Loop 3 (for in) — 600 (671.6)

Safari

Loop 1 (for ;;) — 180 (185.8)
Loop 2 (do – while) — 178 (183.3)
Loop 3 (for in) — 1591 (1615.9)

Chrome

Loop 1 (for ;;) — 180 (191.2)
Loop 2 (do – while) — 159 (167.6)
Loop 3 (for in) — 585 (610.2)

JavaScript traditional for loop is the fastest

I am really surprised with these results. I knew that Mozilla had made some trick to make for loops fast, but I didn’t imagine that Firefox would beat the other two. Also the for in is to be avoided as it is slower. Convenience in this case comes at a price. I also was amazed on how bad the do-while loop performed under Chrome. I retook the test for Google Chrome and it now makes sense, the do-while is faster than the traditional one but still slower than Firefox’s.

I don’t understand this JavaScript performance differences but they certainly need more testing. The only conclusion until now is that the traditional javascript for loop is fast and should be used without second thoughts.

function go(){
    var o = document.getElementById('out');	
 
    var ar = new Array();
    for (var i=0; i < 1000000; i++) {
        ar[i]=i;
    };
 
    o.innerHTML+="Loop 1 (for ;;) ";
    var start =  (new Date()).getTime();
    for (var i=0; i < ar.length; i++) {
        var a = Math.random()*i;
        var b= Math.random()*i;
        var c= Math.round(a-b);
        var d= Math.round(a)-Math.round(b);
    }
    var end = (new Date()).getTime();
    o.innerHTML+="-- "+(end-start);
 
 
    o.innerHTML+="<br/>Loop 2 (do - while) ";
    var start =  (new Date()).getTime();
    var x = ar.length-1;
    do {
        var a = Math.random()*x;
        var b= Math.random()*x;
        var c= Math.round(a-b);
        var d= Math.round(a)-Math.round(b);			
    } while (x--);
    var end = (new Date()).getTime();
    o.innerHTML+="-- "+(end-start);		
 
 
    o.innerHTML+="<br/>Loop 3 (for in) ";
    var start =  (new Date()).getTime();
    for (var i in ar) {
        var a = Math.random()*i;
        var b= Math.random()*i;
        var c= Math.round(a-b);
        var d= Math.round(a)-Math.round(b);
    }
    var end = (new Date()).getTime();
    o.innerHTML+="-- "+(end-start);		
}

Como eu me livrei da DiggBar (e outras tentativas de colocar o sixhat.net dentro de frames)

[ad#ad-2] no2diggbar O Digg começou há algum tempo a colocar os sites que forem submetidos dentro de um frame criando também um url curto para os definir na página principal. A medida permite ao Digg manter os utilizadores no domínio Digg.com através da Diggbar, mas bloqueia a informação do URL do site visitado aos utilizadores, algo que é inadmissível.

Ora a prática de esconder um site de alguém num frame é uma táctica condenável, porque retira visibilidade a quem produz o conteúdo. O Diggbar é assim uma forma muito lame de invadir a casa de outros. Como tal é necessário que o Digg remova a Diggbar, e até lá arranjar uma solução para lhe dar a volta.

Há várias soluções para o problema, a que implementei foi feita em JavaScript e elimina não só a DiggBar, como outras que tentem colocar o sixhat.net num frame.

Para tal basta colocar o seguinte código na secção head do template do site e voilá

 

<SCRIPT LANGUAGE="JavaScript">

 <!--

 if (window != top) top.location.href = location.href;

 // -->

 </SCRIPT>

Depois de todo o heat que recebeu por causa da Diggbar, do digg decidiu que a diggbar somente será visível para os utilizadores que estiverem logged in no digg colocando redirects permanentes (301) para as páginas dos conteúdos linkados.