Olá! Quarta Feira, 10 de Fevereiro de 2010.


Dicas CódigoFonte.net
Quarta Feira, 14 de Junho de 2006

Desempenho de loops Javascript

Vamos ver nesta dica como se comportam os laços Javascript quando a tarefa é iterar entre os campos de um formulário HTML.

Vamos construir uma página com um formulário repleto de campos input type=checkbox e medir o desempenho dos 3 laços for, while e do ... while.

O mais interesante é que os laços são mais eficientes quando se itera os elementos do último ao primeiro, ao invés de iterá-los do primeiro até o último, como é o mais comum.

O formulário:

Nosso formulário para o teste é formado apenas por um enorme número de elementos input type=checkbox. Devido ao grande número, a geração dos inputs é dinâmica: são escritos 2.000 checkboxes na tela através do laço Javascript:


<form name="f" onsubmit="testes(); return false;">
    <script>
        for ( i=0 ; i<2000 ; i++ )
            document.write( "<input name='teste' type='Checkbox'>" );
    </script>
    
    
    <input type="submit" value="testar">
</form>



Há também um botão de ação, que irá disparar os testes ao ser pressionado.

Abaixo do formulário é exibida uma tabela, inicialmente, vazia, onde os resultados serão exibidos.


Por fim, na parte superior do arquivos, estão as funções Javascript que irão testar os laços e, ao final, exibir na tabela inferior os tempos encontrados.


Conclusões:

A conclusão é interessante: o laço for é o mais lento. E, ainda por cima, iterar os campos do primeiro ao último elemento apresenta o menor desempenho.

Os laços while e do ... while apresentam sempre a maior performance, sendo que, a diferença em desempenho quando se itera os elementos do último ao primeiro é significativa.

Além disso, experimente testar a página no navegador Firefox... A diferença em desempenho em relação ao Internet Explorer é absurda...

O código completo:

Abaixo, segue o código completo. Cole o código abaixo em um arquivo .html e teste em seu navegador.


<script>
/** Retorna um elemento atraves do seu ID.
 */
function $( elem ) {
    return document.getElementById( elem );
}
</script>

<script>
/**
 */
function testes() {
    teste1( document.f, 1 );
    teste2( document.f, 2 );
    teste3( document.f, 3 );
    teste4( document.f, 4 );
    teste5( document.f, 5 );
    teste6( document.f, 6 );
    window.status = "OK.";
}
/** Teste utilizando um loop FOR,
 * iterando do INICIO ao FIM.
 */
function teste1( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        for ( i=0 ; i<teste.length ; i++ )
            teste[i].checked = false;
        fim = new Date();
        $( "r1" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
/** Teste utilizando um loop FOR,
 * iterando do FIM ao INICIO.
 */
function teste2( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        for ( i=teste.length-1 ; i>-1 ; i-- )
            teste[i].checked = false;
        fim = new Date();
        $( "r2" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
/** Teste utilizando um loop DO WHILE,
 * iterando do INICIO ao FIM.
 */
function teste3( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        i = 0;
        do {
            teste[i].checked = false;
        } while( i++ < teste.length-1 );
        fim = new Date();
        $( "r3" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
/** Teste utilizando um loop DO WHILE,
 * iterando do FIM ao INICIO.
 */
function teste4( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        i = teste.length - 1;
        do {
            teste[i].checked = false;
        } while( i-- );
        fim = new Date();
        $( "r4" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
/** Teste utilizando um loop WHILE,
 * iterando do INICIO ao FIM.
 */
function teste5( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        i = -1;
        while( i++ < teste.length-1 ) {
            teste[i].checked = false;
        }
        fim = new Date();
        $( "r5" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
/** Teste utilizando um loop WHILE,
 * iterando do FIM ao INICIO.
 */
function teste6( f, n ) {
    window.status = "Teste "+n+". Aguarde...";
    with ( f ) {
        ini = new Date();
        i = teste.length;
        while( i-- > 0 ) {
            teste[i].checked = false;
        }
        fim = new Date();
        $( "r6" ).innerHTML = ((fim - ini)/1000)+"s.";
    }
    window.status = "Teste "+n+". OK.";
}
</script>

<h3>Desempenho de loops Javascript:</h3>
<hr>


<form name="f" onsubmit="testes(); return false;">
    <script>
        for ( i=0 ; i<2000 ; i++ )
            document.write( "<input name='teste' type='Checkbox'>" );
    </script>
    
    
    <input type="submit" value="testar">
</form>


<h4>Atenção:</h4>
O teste pode demorar alguns segundos.
Para uma melhlor medição, ao pressionar o botão 'testar', não faça mais nada no seu computador, apenas aguarde o fim dos testes.



<h4>Resultados:</h4>
<table cellpadding="3" cellspacing="0" border="1" style="border-collapse: collapse;">
    <tr>
        <th>for 0..n</th>
        <th>for n..0</th>
        <th>do while 0..n</th>
        <th>do while n..0</th>
        <th>while 0..n</th>
        <th>while n..0</th>
    </tr>
    <tr>
        <td id="r1"></td>
        <td id="r2"></td>
        <td id="r3"></td>
        <td id="r4"></td>
        <td id="r5"></td>
        <td id="r6"></td>
    </tr>
</table>

Comentários do artigo [Novo comentário]

Nenhum comentário, seja o primeiro a comentar.
Para adicionar um comentário você deve efetuar o login


Gostou do CódigoFonte.net? Quer indicar a um amigo?
Preencha os campos a seguir.
Seu Nome:
Seu E-mail:
E-mail de seu Amigo:






Melhor Visualizado com
800x600 de Resolução

CodigoFonte.net » CodigoFonte.eti.br » Compre De Tudo » Meu Mural » PelamorDeDeus » Todos os Direitos Reservados © 2002/2008

Procurando Notebooks, Câmeras Digitais, iPhones?

CompreDeTudo.com