118 votes

Comment puis-je évaluer le code JavaScript ?

Existe-t-il un paquet qui m'aide à évaluer le code JavaScript ? Je ne fais pas référence à Firebug et aux outils de ce type.

Je dois comparer deux fonctions JavaScript différentes que j'ai implémentées. Je suis très familier avec le Benchmark de Perl ( Benchmark.pm ) et je cherche quelque chose de similaire en JavaScript.

L'accent mis sur l'évaluation comparative du code JavaScript est-il excessif ? Puis-je m'en sortir en ne chronométrant qu'une seule exécution des fonctions ?

0 votes

Il semble que ce soit un double : stackoverflow.com/search?q=javascript+profiler

0 votes

0 votes

Je sais que ce n'est pas infaillible, mais c'est quand même lié : parfois, on veut juste savoir. comment mesurer le temps d'exécution d'une fonction .

121voto

broofa Points 21663

jsperf.com est le site de référence pour tester les performances des JS. Commencez par là. Si vous avez besoin d'un cadre pour exécuter vos propres tests à partir de la ligne de commande ou de scripts utilisez Benchmark.js la bibliothèque sur laquelle jsperf.com est construit.

Note : Toute personne testant du code Javascript devrait s'informer sur les pièges des "microbenchmarks" (petits tests qui ciblent une fonctionnalité ou une opération spécifique, plutôt que des tests plus complexes basés sur des modèles de code réels). De tels tests peuvent être utiles mais sont sujets à l'inexactitude en raison de la façon dont les runtimes JS modernes fonctionnent. Présentation de Vyacheslav Egorov sur la performance et le benchmarking vaut la peine d'être regardé pour avoir une idée de la nature du ou des problèmes.

Editar: Suppression des références à mon travail sur JSLitmus, qui n'est plus pertinent ni utile.

3 votes

Mise à jour : utilisez jsperf.com - il s'est beaucoup amélioré et fonctionne très bien pour ce genre de choses. jslitmus fonctionne toujours, mais n'a pas été développé activement depuis un certain temps.

0 votes

C'est la réponse supérieure. +1

1 votes

Je voulais utiliser jsperf, mais il semble compter combien de fois il peut exécuter le code pendant une période donnée, plutôt que de chronométrer l'appel réel pour N boucles. J'aimerais qu'il y ait une option pour choisir.

38voto

Sasha Chedygov Points 36783

Il suffit de chronométrer plusieurs itérations de chaque fonction. Une itération ne suffira probablement pas, mais (en fonction de la complexité de vos fonctions) une centaine, voire un millier d'itérations, devraient suffire.

Firebug dispose également d'un Profileur si vous voulez voir quelles parties de votre fonction la ralentissent.

Editar: Pour les futurs lecteurs, la réponse ci-dessous recommandant JSPerf devrait être la réponse correcte. Je supprimerais bien la mienne, mais je ne peux pas car elle a été sélectionnée par le PO. L'analyse comparative ne se limite pas à l'exécution de nombreuses itérations, et JSPerf s'en charge pour vous.

12 votes

Simplement chronométrer un nombre prédéfini d'itérations de votre code est pas du tout à l'épreuve des balles . De plus, le fait d'avoir Firebug ouvert désactive le compilateur Just-In-Time (JIT) de Firefox, ce qui signifie que les tests seront exécutés dans l'interpréteur, c'est-à-dire beaucoup plus lentement qu'ils ne le seraient autrement. L'utilisation du profileur de Firebug ne vous donnera pas les résultats escomptés.

1 votes

@Mathias : Eh bien, pour être juste, cette réponse est vraiment vieille.

2 votes

Bien sûr, sans vouloir vous offenser, mon pote. J'ai juste pensé que je ferais un commentaire pour référence future maintenant que plus de recherches ont été faites sur le sujet.

20voto

fncomp Points 3194

J'ai utilisé cette mise en œuvre simple de la réponse de @musicfreaks. Il n'y a pas de fonctionnalités, mais c'est vraiment facile à utiliser. Ce bench(function(){return 1/2;}, 10000, [], this) calculera 1/2 10 000 fois.

/**
 * Figure out how long it takes for a method to execute.
 * 
 * @param {Function} method to test 
 * @param {number} iterations number of executions.
 * @param {Array} args to pass in. 
 * @param {T} context the context to call the method in.
 * @return {number} the time it took, in milliseconds to execute.
 */
var bench = function (method, iterations, args, context) {

    var time = 0;
    var timer = function (action) {
        var d = Date.now();
        if (time < 1 || action === 'start') {
            time = d;
            return 0;
        } else if (action === 'stop') {
            var t = d - time;
            time = 0;    
            return t;
        } else {
            return d - time;    
        }
    };

    var result = [];
    var i = 0;
    timer('start');
    while (i < iterations) {
        result.push(method.apply(context, args));
        i++;
    }

    var execTime = timer('stop');

    if ( typeof console === "object") {
        console.log("Mean execution time was: ", execTime / iterations);
        console.log("Sum execution time was: ", execTime);
        console.log("Result of the method call was:", result[0]);
    }

    return execTime;  
};

9voto

Mathias Bynens Points 41065

Il est vraiment difficile d'écrire des tests de référence décents entre navigateurs. Simplement chronométrer un nombre prédéfini d'itérations de votre code est pas du tout à l'épreuve des balles .

Comme @broofa l'a déjà suggéré, vérifiez les points suivants jsPerf . Il utilise Benchmark.js dans les coulisses.

2voto

lukins Points 21

Si vous écrivez un benchmark script personnalisé, veillez à noter que certains navigateurs n'appliquent les manipulations de dom qu'après la fin de la fonction dans laquelle elles sont définies. Plus de détails ici http://www.quirksmode.org/blog/archives/2009/08/when_to_read_ou.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X