Comment puis-je comparer le code JavaScript? [fermé]

104

Existe-t-il un package qui m'aide à évaluer le code JavaScript? Je ne parle pas de Firebug et de tels outils.

J'ai besoin de comparer 2 fonctions JavaScript différentes que j'ai implémentées. Je connais très bien le module Benchmark ( Benchmark.pm ) de Perl et je recherche quelque chose de similaire en JavaScript.

L'accent mis sur l'analyse comparative du code JavaScript est-il allé trop loin? Puis-je me contenter de chronométrer une seule exécution des fonctions?

Morse ionique
la source
Semble être un dup: stackoverflow.com/search?q=javascript+profiler
steamer25
Je sais que ce n'est pas à toute épreuve et tout, mais lié quand même: parfois on veut juste savoir comment mesurer le temps mis par une fonction à exécuter .
Skippy le Grand Gourou
1
Je peux trouver un bon outil de référence JavaScript ici: jsben.ch
EscapeNetscape

Réponses:

36

Il suffit de chronométrer plusieurs itérations de chaque fonction. Une itération ne suffira probablement pas, mais (selon la complexité de vos fonctions) quelque part plus proche de 100 ou même 1000 itérations devrait faire le travail.

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

Edit: Pour les futurs lecteurs, la réponse ci-dessous recommandant JSPerf devrait être la bonne réponse. Je supprimerais le mien, mais je ne peux pas car il a été sélectionné par l'OP. L'analyse comparative ne se résume pas à exécuter de nombreuses itérations, et JSPerf s'en charge pour vous.

Sasha Chedygov
la source
12
Le simple chronométrage d'un nombre prédéfini d'itérations de votre code n'est pas du tout à toute épreuve . De plus, l'ouverture de Firebug désactive le compilateur Just-In-Time (JIT) de Firefox, ce qui signifie que les tests s'exécuteront dans l'interpréteur, c'est-à-dire beaucoup plus lentement qu'ils ne le feraient autrement. L'utilisation du profileur de Firebug ne vous donnera pas les résultats attendus.
Mathias Bynens
1
@Mathias: Eh bien, pour être honnête, cette réponse est vraiment ancienne.
Sasha Chedygov
2
Bien sûr, pas de compagnon d'offense. Je pensais juste commenter pour référence future maintenant que plus de recherches ont été faites sur le sujet.
Mathias Bynens
4
Ou utilisez jsben.ch puisque jsperf est en panne
EscapeNetscape
118

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

Remarque: toute personne testant du code Javascript doit se renseigner 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). Ces tests peuvent être utiles mais sont sujets à des inexactitudes en raison du fonctionnement des environnements d'exécution JS modernes. La présentation de Vyacheslav Egorov sur la performance et l'analyse comparative vaut la peine d'être regardée pour avoir une idée de la nature du ou des problèmes.

Edit: Suppression des références à mon travail JSLitmus car il n'est tout simplement plus pertinent ou utile.

Broofa
la source
3
Mise à jour: utilisez simplement 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é activement développé depuis un certain temps.
broofa le
C'est la meilleure réponse. +1
Justin Force
1
Je voulais utiliser jsperf, mais il semble compter combien de fois il peut exécuter le code pendant une période de temps, plutôt que de chronométrer l'appel réel pour N boucles. J'aurais aimé qu'ils aient la possibilité de choisir.
Jeach
1
@Jeach - jsperf donne "opérations / seconde". Multipliez simplement cette valeur par le temps (en secondes) pendant lequel le code sera exécuté.
broofa
4
Mise à jour: jsperf n'est plus en ligne, et il n'y a pas de mot quand il sera de nouveau en ligne. Voir ce fil de discussion github pour plus d'informations.
James Gould
74

Il suffit d'ajouter un minuteur rapide au mix, ce que quelqu'un peut trouver utile:

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

Idéalement, il serait placé dans une classe et non utilisé comme un global comme je l'ai fait à des fins d'exemple ci-dessus. L'utiliser serait assez simple:

var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console
Kenny
la source
6
Bon usage des fermetures ici.
Dandy
12
Pour un résultat plus précis, on pourrait vouloir utiliser à la performance.now()place de Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier
Juste ce dont j'avais besoin - un tempsIt ()
Gishu
1
Version TypeScript: pastebin.com/gCs9CB5F
Alexander Taylor
1
Pour node.js, vous pouvez utiliser process.hrtime () pour obtenir une résolution nanoseconde.
Xeoncross
56

Un moyen simple.

console.time('test');
console.timeEnd('test');
stadnik0ff
la source
3
Cela devrait être la réponse acceptée. L'utilisation d'un service tiers n'est parfois pas pratique et l'utilisation d'une simple fonctionnalité intégrée est excellente.
brainbag
1
@brainbag - La question portait sur l'analyse comparative, qui implique plus que simplement chronométrer la durée d'exécution d'un peu de code. De plus, les minuteries de console ne sont utiles que si le code en question prend plus de 1 milliseconde (la limite de leur résolution).
broofa le
Vous pouvez également exécuter votre benchmark dans une suite de tests, qui nécessitent d'avoir accès à la valeur du minuteur.
JamesDev
20

J'utilise cette implémentation simple de la réponse @musicfreaks. Il n'y a pas de fonctionnalités, mais c'est vraiment facile à utiliser. Cela bench(function(){return 1/2;}, 10000, [], this)calculera 1/2 10000 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;  
};
fncomp
la source
9

Il est vraiment difficile d'écrire des benchmarks inter-navigateurs décents. Le simple chronométrage d'un nombre prédéfini d'itérations de votre code n'est pas du tout à toute épreuve .

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

Mathias Bynens
la source
1

Si vous avez besoin de quelque chose de simple, vous pouvez faire comme ceci:

'use strict'
console.clear()

const powerOf = x => y => Math.pow(x, y)
const powerOfThree = powerOf(3)

function performanceCalc(fn, ...params) {
    const start = +new Date()
    const result = fn(...params)
    const end = +new Date()

    console.log(`Result: ${result}. Execution Time: ${end - start} ms`)
}

performanceCalc(powerOfThree, 2)

Voici un exemple du code

Vlad Bezden
la source
Simple était certainement la meilleure option dans mon cas ... écrire des tests pour comparer les temps de réponse pour l'API (pas besoin de temps extrêmement précis).
kashiraja