Wie kann ich JavaScript-Code vergleichen? [geschlossen]


104

Gibt es ein Paket, mit dem ich JavaScript-Code vergleichen kann? Ich beziehe mich nicht auf Firebug und solche Tools.

Ich muss 2 verschiedene JavaScript-Funktionen vergleichen, die ich implementiert habe. Ich bin mit Perls Benchmark- Modul ( Benchmark.pm ) sehr vertraut und suche nach etwas Ähnlichem in JavaScript.

Ist der Schwerpunkt auf dem Benchmarking von JavaScript-Code über Bord gegangen? Kann ich mit dem Timing nur eines Durchgangs der Funktionen durchkommen?




Ich weiß, dass es nicht kugelsicher ist, aber trotzdem verwandt: Manchmal möchte man nur wissen, wie man die Zeit misst, die eine Funktion für die Ausführung benötigt .
Skippy le Grand Gourou

1
Ich gute JavaScript-Benchmark-Tool finden Sie hier: jsben.ch
EscapeNetscape

Antworten:


36

Nehmen Sie einfach mehrere Iterationen jeder Funktion vor. Eine Iteration wird wahrscheinlich nicht ausreichen, aber (je nachdem, wie komplex Ihre Funktionen sind) sollte irgendwo näher an 100 oder sogar 1.000 Iterationen die Arbeit erledigen.

Firebug hat auch einen Profiler, wenn Sie sehen möchten, welche Teile Ihrer Funktion ihn verlangsamen.

Bearbeiten: Für zukünftige Leser sollte die folgende Antwort, die JSPerf empfiehlt, die richtige Antwort sein. Ich würde meine löschen, aber ich kann nicht, weil sie vom OP ausgewählt wurde. Benchmarking ist viel mehr als nur das Ausführen vieler Iterationen, und JSPerf erledigt dies für Sie.


12
Das einfache Timing einer vordefinierten Anzahl von Iterationen Ihres Codes ist überhaupt nicht kugelsicher . Wenn Firebug geöffnet ist, wird der JIT-Compiler (Just-In-Time) von Firefox deaktiviert. Dies bedeutet, dass die Tests im Interpreter ausgeführt werden, dh viel langsamer als sonst. Wenn Sie den Firebug-Profiler verwenden, erhalten Sie nicht die erwarteten Ergebnisse.
Mathias Bynens

1
@ Mathias: Nun, um fair zu sein, diese Antwort ist wirklich alt.
Sasha Chedygov

2
Sicher, nichts für ungut. Ich dachte nur, ich würde es jetzt kommentieren, da mehr Forschung zu diesem Thema durchgeführt wurde.
Mathias Bynens

4
Oder verwenden Sie jsben.ch, da jsperf nicht verfügbar ist
EscapeNetscape

118

jsperf.com ist die Website zum Testen der JS-Leistung. Beginnen Sie dort. Wenn Sie ein Framework zum Ausführen Ihrer eigenen Tests über die Befehlszeile oder Skripte benötigen, verwenden Sie Benchmark.js , die Bibliothek, auf der jsperf.com basiert.

Hinweis: Jeder, der Javascript-Code testet, sollte sich über die Fallstricke von "Mikrobenchmarks" informieren (kleine Tests, die auf eine bestimmte Funktion oder Operation abzielen, anstatt komplexere Tests, die auf realen Codemustern basieren). Solche Tests können nützlich sein, sind jedoch aufgrund der Funktionsweise moderner JS-Laufzeiten anfällig für Ungenauigkeiten. Vyacheslav Egorovs Präsentation zu Leistung und Benchmarking ist sehenswert, um ein Gefühl für die Art der Probleme zu bekommen.

Bearbeiten: Verweise auf meine JSLitmus-Arbeit wurden entfernt, da sie einfach nicht mehr relevant oder nützlich ist.


3
Update: Verwenden Sie einfach jsperf.com - es ist viel besser geworden und funktioniert für solche Dinge wirklich gut. jslitmus funktioniert immer noch, wurde aber seit einiger Zeit nicht mehr aktiv entwickelt.
Broofa

Dies ist die überlegene Antwort. +1
Justin Force

1
Ich wollte jsperf verwenden, aber es scheint zu zählen, wie oft der Code für einen bestimmten Zeitraum ausgeführt werden kann, anstatt den tatsächlichen Aufruf für N Schleifen zu planen. Ich wünschte, sie hätten eine Option zur Auswahl.
Jeach

1
@Jeach - jsperf gibt "Operationen / Sekunde" an. Multiplizieren Sie diesen Wert einfach mit der Zeit (in Sekunden), für die Ihr Code ausgeführt wird.
Broofa

4
Update: jsperf ist nicht mehr online und es gibt kein Wort darüber, wann es wieder online sein wird. Weitere Informationen finden Sie in diesem Github-Thread .
James Gould

73

Fügen Sie dem Mix einfach einen schnellen Timer hinzu, den jemand vielleicht nützlich findet:

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');
        }
    }
};

Im Idealfall wird es in eine Klasse eingeordnet und nicht wie ich es zum Beispiel oben als global verwendet habe. Die Verwendung wäre ziemlich einfach:

var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console

6
Gute Verwendung von Verschlüssen hier.
Dandy

12
Für ein genaueres Ergebnis möchten Sie möglicherweise performance.now()anstelle von Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier

Genau das, was ich brauchte - ein timeIt ()
Gishu

1
TypeScript-Version: pastebin.com/gCs9CB5F
Alexander Taylor

1
Für node.js können Sie process.hrtime () verwenden , um die Auflösung von Nanosekunden zu erhalten.
Xeoncross

56

Einfach einfach.

console.time('test');
console.timeEnd('test');

3
Dies sollte die akzeptierte Antwort sein. Die Verwendung eines Drittanbieter-Dienstes ist manchmal nicht bequem, und die Verwendung einer einfachen integrierten Funktion ist hervorragend.
Brainbag

1
@brainbag - Die Frage betraf das Benchmarking, bei dem es nicht nur darum geht, wie lange ein bisschen Code ausgeführt wird. Konsolen-Timer sind auch nur dann nützlich, wenn der betreffende Code länger als 1 Millisekunde dauert (die Grenze ihrer Auflösung).
Broofa

Möglicherweise möchten Sie Ihren Benchmark auch in einer Testsuite ausführen, für die Zugriff auf den Timerwert erforderlich ist.
JamesDev

20

Ich habe diese einfache Implementierung von @musicfreaks Antwort verwendet. Es gibt keine Funktionen, aber es ist wirklich einfach zu bedienen. Dies bench(function(){return 1/2;}, 10000, [], this)wird 1/2 10.000 mal berechnet.

/**
 * 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;  
};

9

Es ist wirklich schwer, anständige browserübergreifende Benchmarks zu schreiben. Das einfache Timing einer vordefinierten Anzahl von Iterationen Ihres Codes ist überhaupt nicht kugelsicher .

Schauen Sie sich, wie @broofa bereits vorgeschlagen hat, jsPerf an . Es verwendet Benchmark.js hinter den Kulissen.



1

Wenn Sie etwas Einfaches benötigen, können Sie Folgendes tun:

'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)

Hier ist ein Beispiel für den Code


Einfach war definitiv die beste Option in meinem Fall ... einige Tests zu schreiben, um die Antwortzeiten für API zu vergleichen (keine Notwendigkeit für extrem genaue Zeiten).
Kashiraja
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.