Parcourir un tableau en JavaScript, méthodes et benchmarks

Démonstration et comparaison des trois méthodes pour parcourir le contenu d'un tableau. Nous allons calculer le temps d'exécution de for(), for in et forEach.

for ()

Une boucle simple qui incrémente un indice et accède aux éléments successifs par cet indice.

var x = ["un", "deux", "trois" ];
for(var i= 0; i < x.length; i++)
{
     document.write(x[i]);
}

C'est la méthode la plus rapide.

for in

Une boucle for in est l'équivalent du foreach de PHP et autres langages, elle assigne directement les éléments du tableau à une variable.

for(var i in x)
{
     document.write(x[i]);
}

Cette méthode est la moins performante.

Firefox offre une syntaxe particulière.

for each(var i in x)
{
     document.write(i);
}

Mais ce n'est pas compatible avec d'autres navigateur et donc il est inutile de s'y attarder.

La méthode forEach

Elle a été ajoutée à la version 1.6 de JavaScript et est supportée par Firefox et Chrome puis par Internet Explorer 9.

x.forEach(function(y) 
{ 
   document.write(y); 
}
);

On peut associer la méthode directement à un tableau litéral:

["un", "deux", "trois"].forEach(function(y) { document.write(y); }); 

Si l'on aime le code compact, cela convient bien, mais c'est moins performant que la boucle for simple.

D'autres méthodes sont encore possibles mais peu lisibles.

Comparons les temps d'exécution...

Pour comparer les performances, on réalise une boucle avec chacune des méthodes. Le temps de départ est obtenu par ces instructions:

var newdate = new Date();
var fordiff = newdate.getTime();

Ce temps est pris au départ et à la fin de l'exécution. La différence en millisecondes est ce qui est affiché.

Le test comparatif donne cet ordre de rapidité d'exécution sur tous navigateurs:

  1. for()
  2. forEach (non supporté par IE avant IE9)
  3. for in

Les valeurs absolues dépendent du matériel, seules comptent les valeurs relatives. Elle sont dans les mêmes proportions avec tous les navigateurs.

Si on exclue les méthodes qui ne sont pas compatibles avec tous les navigateurs, restent for() et for in.
La seconde est plus simple mais beaucoup moins performante. On ne l'utilisera que si le temps d'exécution n'est pas critique.

En voici la démonstration en ligne...

for()

var x = ["un", "deux", "trois" ];
for(var i= 0; i < x.length; i++)
{
     document.write(x[i]);
}
Résultat:

for in

for(var i in x)
{
     document.write(x[i]);
}
Résultat:

Méthode forEach

Elle a été ajoutée dans JavaScript 1.6.

x.forEach(function(y) 
{ 
   document.write(y); 
}
);

Avec un litéral:

["un", "deux", "trois"].forEach(function(y) { document.write(y); }); 

Les temps d'exécution...

Code source complet:

var fortime = 0;
var forintime = 0;
var foreachtime = 0;
/* creation d'un tableau */
var x = new Array();
for(var i = 0; i < 100000; i++)
{
x[i] = "12345";
}
function mainloop()
{
var newdate = new Date();
var fordiff = newdate.getTime();
for(var j = 0; j < 10; j++)
{
for(var i= 0; i < x.length; i++)
{
var z = x[i];
}
}
newdate = new Date();
fortime = fortime + (newdate.getTime() - fordiff);
newdate = new Date();
var forindiff = newdate.getTime();
for(var j = 0; j < 10; j++)
{
for(var i in x)
{
var z = i;
}
}
newdate = new Date();
forintime = forintime + (newdate.getTime() - forindiff);
newdate = new Date();
var foreachdiff = newdate.getTime();
for(var j = 0; j < 10; j++)
{
x.forEach(function(y)
{
var z = y;
});
}
newdate = new Date();
foreachtime = foreachtime + (newdate.getTime() - foreachdiff);
}
mainloop();
Forum

Nouveau benchmarks pour JavaScript: For, For In, ForEach, JQuery.each

29-02-2012 18:44:45

ImmortalPC

Bonjour, J'ai beaucoup apprécié vos benchmarks. Mais il manquait quelques tests suplémentaires. J'ai donc ajouter un test avec la lib JQuery. J'ai aussi doublé le test pour faire un bench sur les Array et sur les Object

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <title>Ma page HTML</title>
</head>
<body>
<script type="text/javascript">
var fortime = 0;
var forintime = 0;
var foreachtime = 0;
var eachJQuery = 0;
var x = null;

function mainloop()
{
    fortime = 0;
    forintime = 0;
    foreachtime = 0;
    eachJQuery = 0;

    // Test sur le FOR
    if( x.length ){
        var newdate = new Date();
        var fordiff = newdate.getTime();
        for(var j = 0; j < 10; j++)
        {
            for(var i= 0; i < x.length; i++)
            {
                var z = x[i];
            }
        }
        newdate = new Date();
        fortime = fortime + (newdate.getTime() - fordiff);
    }else{
        fortime = 'fail';
    }

    // Test sur le FOR IN
    newdate = new Date();
    var forindiff = newdate.getTime();
    for(var j = 0; j < 10; j++)
    {
        for(var i in x)
        {
            var z = i;
        }
    }
    newdate = new Date();
    forintime = forintime + (newdate.getTime() - forindiff);

    // Test sur le FOREACH
    if( x.forEach ){
        newdate = new Date();
        var foreachdiff = newdate.getTime();
        for(var j = 0; j < 10; j++)
        {
            x.forEach(function(y)
            {
               var z = y;
            });
        }
        newdate = new Date();
        foreachtime = foreachtime + (newdate.getTime() - foreachdiff);
    }else{
        foreachtime = 'fail';
    }

    // Test sur le EACH de JQuery
    newdate = new Date();
    var eachJQuerydiff = newdate.getTime();
    for(var j = 0; j < 10; j++)
    {
        $.each(x, function(index, value) {
            var z = value;
        });
    }
    newdate = new Date();
    eachJQuery = eachJQuery + (newdate.getTime() - eachJQuerydiff);
}

// Version Array
x = new Array();
for(var i = 0; i < 100000; i++)
{
    x[i] = "12345";
}
mainloop();
document.body.innerHTML =
    '<b>Version Array</b><br />'
    +'for: '+fortime+'<br />'
    +'for in: '+forintime+'<br />'
    +'foreach: '+foreachtime+'<br />'
    +'each JQuery: '+eachJQuery+'<br /><br />';

// Version Objet
x = new Object();
for(var i = 0; i < 100000; i++)
{
    x['prop'+i] = "12345";
}
mainloop();

document.body.innerHTML +=
    '<b>Version Object</b><br />'
    +'for: '+fortime+'<br />'
    +'for in: '+forintime+'<br />'
    +'foreach: '+foreachtime+'<br />'
    +'each JQuery: '+eachJQuery+'<br />';
</script>
</body>
</html>
Cordialement I-PC PS: Ton filtre anti url est plus gênant que fonctionnel. Pour le contourner il y a le BBCode et la balise url tel que: [.url=immortalpc.info]lien[./url] ( suppr . )
29-02-2012 20:35:15

webmaster

Bonjour Merci pour cette contribution. Pour le filtre, après une longue expérience sans, il s'avère malheureusement nécessaire à cause du spam et des liens vers des sites vraiment pas pour tout public.
© 2010-2022 Xul.fr