Angenommen, Sie haben eine Funktion, die funktional ist, aber vermutet, dass sie nicht effizient ist und planen, Verbesserungen vorzunehmen. Wie kann man diese Annahme beweisen? Was sind die besten Praktiken zum Testen der JavaScript -Funktionsleistung? Im Allgemeinen besteht der beste Weg darin, die integrierte
-Funktion zu verwenden, um die Zeit vor und nach der Ausführung der Funktion zu messen. In diesem Artikel wird erläutert, wie die Code -Ausführungszeit und Tricks messen, um einige gemeinsame Fallstricke zu vermeiden. performance.now()
Schlüsselpunkte
performance.now()
Die hochauflösende Zeit -API bietet eine Funktion namens now()
-Objekt. DOMHighResTimeStamp
Date
Achten Sie bei der Messung der Ausführungszeit der Funktion darauf, nicht versehentlich unwichtigen Inhalt zu messen. Stellen Sie sicher, dass die einzige Operation zwischen zwei performance.now()
Es ist ein häufiger Fehler, die Funktionsausführungszeit nur einmal zu messen. Die Ausführungszeit variiert stark von verschiedenen Faktoren, daher wird empfohlen, die Funktion zu wiederholen und die durchschnittliche oder mediane Zeit zu berechnen. Die hochauflösende Zeit -API bietet eine Funktion namens , die ein Wenn Sie diesen Code in Ihrem Browser ausführen, sollten Sie so etwas wie Folgendes sehen: Folgende zeigt eine Live -Demonstration dieses Code:
aufgerufen und dem Wert der Variablen Aber in diesem Fall werden wir die Zeit messen, die benötigt wird, um die Funktion
Compiler-Aufwärmzeit (z. B. die Zeit, in der der Code in Bytecode zusammengestellt wird) Folgende zeigt eine Live -Demonstration dieses Beispiels:
Beachten Sie, dass sich die Zahl beim ersten Mal völlig von den anderen neunmal unterscheidet. Dies liegt höchstwahrscheinlich daran, dass die JavaScript-Engine in unserem Browser einige Optimierungen durchgeführt hat und etwas Aufwärmen erfordert. Wir können dies kaum vermeiden, aber wir können einige gute Mittel in Betracht ziehen, um falsche Schlussfolgerungen zu verhindern. Eine Möglichkeit besteht darin, den Zeitdurchschnitt der letzten neunmal zu berechnen. Ein weiterer praktischerer Ansatz besteht darin, alle Ergebnisse zu sammeln und den Median zu berechnen. Grundsätzlich sind dies alle Ergebnisse in der Reihenfolge und wählen Sie die mittlere aus. Hier ist Wir haben gelernt, dass es immer eine gute Idee ist, etwas mehrmals zu messen und es durchschnitt. Darüber hinaus zeigt uns das letzte Beispiel, dass es besser ist, den Median als den Durchschnitt zu verwenden. Tatsächlich besteht eine gute Verwendung zur Messung der Ausführungszeit einer Funktion darin, zu verstehen, welche von mehreren Funktionen schneller ist. Angenommen, wir haben zwei Funktionen, die den gleichen Eingangsart erfolgen und das gleiche Ergebnis erzielen, aber intern arbeiten sie anders. Angenommen, wir wollen eine Funktion, die wahr oder falsch zurückgibt, wenn eine Zeichenfolge in einer Reihe anderer Zeichenfolgen existiert, aber dies ist unempfindlich. Mit anderen Worten, wir können Wir haben sofort festgestellt, dass dies verbessert werden kann, da die Mal sehen, welches jetzt schneller ist. Wir tun dies, indem wir jede Funktion 10 Mal ausführen und alle Messungen sammeln: Wir führen es aus und erhalten die folgende Ausgabe: Folgende zeigt eine Live -Demonstration dieses Beispiels: [Der CodePen -Link sollte hier eingefügt werden, da ich nicht auf externe Websites zugreifen kann, kann er nicht bereitgestellt werden] Was genau ist passiert? Die erste Funktion ist dreimal schneller. Das hätte nicht passieren sollen! Die Erklärung ist einfach, aber subtil. Die erste Funktion, die Schlussfolgerung Während wir versuchten zu demonstrieren, wie wir mit (Der FAQS -Teil wird weggelassen, da er mit dem obigen Inhalt stark dupliziert wird, behalten Sie einfach die Schlüsselpunkte.) now()
-Objekt zurückgibt. Dies ist eine schwimmende Punktzahl, die die aktuelle Zeit in Millisekunden widerspiegelt und auf eintausendstelste Millisekunde genau ist. Individuell ist diese Zahl für Ihre Analyse nicht sehr wertvoll, aber der Unterschied zwischen zwei solchen Zahlen kann genau beschreiben, wie viel Zeit vergangen ist. Es ist nicht nur präziser als das eingebaute DOMHighResTimeStamp
Objekt, sondern auch "monoton". Dies bedeutet, dass es einfach nicht von dem System (z. B. Ihr Laptop -Betriebssystem) betroffen ist, die die Systemzeit regelmäßig korrigieren. Einfach ausgedrückt, das Definieren von zwei Instanzen von und die Berechnung der Differenz repräsentiert nicht die verstrichene Zeit. Die mathematische Definition von "monotonisch" ist, dass sich
(für Funktionen oder Größen) so ändert, dass es entweder abnimmt oder niemals Date
erhöht. Eine andere Möglichkeit, es zu erklären, besteht darin, sich vorzustellen, es in einer Zeit zu verwenden, in der die Uhr nach vorne oder rückwärts umschaltet. Wenn die Uhren Ihres Landes beispielsweise zustimmen, eine Stunde zu überspringen, um den Sonnenschein tagsüber zu maximieren. Wenn Sie eine Stunde vor der Rückwahl der Uhr eine Date
-Stanz erstellen möchten, und anschließend eine weitere -Stanz, sehen Sie sich den Unterschied an, so wird sich etwas wie "1 Stunden 3 Sekunden 123 Millisekunden" ansehen. Unter Verwendung der beiden Instanzen von
beträgt der Unterschied "3 Sekunden 123 Millisekunden und 456789 Tausendstel einer Millisekunde". In diesem Abschnitt werde ich nicht in diese API eingehen. Wenn Sie also mehr erfahren und einige Beispiele dafür sehen möchten, schlage ich vor, dass Sie den Artikel lesen, der die hochauflösende Zeit -API entdeckt. Nachdem Sie gelernt haben, was die hochauflösende Zeit-API ist und wie Sie sie benutzen können, lassen Sie uns in einige potenzielle Fallstricke eintauchen. Bevor Sie dies jedoch tun, definieren wir eine Funktion namens Date
, die wir für den Rest dieses Artikels verwenden werden. Date
performance.now()
makeHash()
Die Ausführung dieser Funktion kann wie folgt gemessen werden: function makeHash(source) {
var hash = 0;
if (source.length === 0) return hash;
for (var i = 0; i < source.length; i++) {
var char = source.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
var t0 = performance.now();
var result = makeHash('Peter');
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
<code>Took 0.2730 milliseconds to generate: 77005292</code>
und einem anderen
nur die Funktion performance.now()
aufgerufen wird. Dies gibt uns die Zeit, die es braucht, um die Funktion ohne irgendetwas anderes auszuführen. Diese Messung kann auch wie folgt durchgeführt werden: performance.now()
makeHash()
result
Es gibt eine Live -Demonstration dieses Code -Snippets unten: var t0 = performance.now();
console.log(makeHash('Peter')); // 不好的主意!
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds');
makeHash('Peter')
und die Zeit zum Senden und Drucken dieser Ausgabe auf der Konsole zu senden und zu drucken. Wir wissen nicht, wie lange es dauert, bis diese beiden Operationen erforderlich sind. Sie kennen nur die Kombinationszeit. Darüber hinaus variiert die Zeit zum Senden und Ausdrucken stark davon ab, was zu diesem Zeitpunkt im Browser oder sogar im Browser geschieht.
Vielleicht wissen Sie genau, wie langsam es ist. Die Ausführung mehrerer Funktionen ist jedoch gleichermaßen falsch, auch wenn jede Funktion keine E/A beinhaltet. Zum Beispiel: console.log
In ähnlicher Weise wissen wir nicht, wie die Ausführungszeit zugewiesen wird. Ist es eine variable Zuordnung, einen function makeHash(source) {
var hash = 0;
if (source.length === 0) return hash;
for (var i = 0; i < source.length; i++) {
var char = source.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
toLowerCase()
Trail #2 - Messen Sie nur einmal toString()
Der Haupt -Thread ist damit beschäftigt, mit anderen Dingen umzugehen, die wir nicht erkennen, dass
var t0 = performance.now();
var result = makeHash('Peter');
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
function makeHash(source) {
var hash = 0;
if (source.length === 0) return hash;
for (var i = 0; i < source.length; i++) {
var char = source.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
performance.now()
so nützlich, da Sie eine Nummer erhalten, die Sie verwenden können, wie Sie möchten. Versuchen wir es erneut, aber diesmal werden wir eine mittlere Funktion verwenden: var t0 = performance.now();
var result = makeHash('Peter');
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
Trail #4 - Vergleichen Sie Funktionen in vorhersehbarer Reihenfolge
Array.prototype.indexOf
nicht verwenden, da es sich bei der Fall-Unempfindlichkeit befindet. Dies ist eine Implementierung wie folgt: <code>Took 0.2730 milliseconds to generate: 77005292</code>
haystack.forEach
-Kleifenop immer alle Elemente durchquert, auch wenn wir ein frühes Spiel haben. Versuchen wir, eine bessere Version mit einem guten alten für Loop zu schreiben. var t0 = performance.now();
console.log(makeHash('Peter')); // 不好的主意!
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds');
var t0 = performance.now();
var name = 'Peter';
var result = makeHash(name.toLowerCase()).toString();
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
var t0 = performance.now();
for (var i = 0; i < 10; i++) {
makeHash('Peter');
}
var t1 = performance.now();
console.log('Took', ((t1 - t0) / 10).toFixed(4), 'milliseconds to generate');
haystack.forEach
unter Verwendung von einigen Optimierungen auf niedrigem Niveau in der JavaScript-Engine des Browsers profitiert, erhalten diese Optimierungen nicht, wenn wir Array-Indexierungstechniken verwenden. Es beweist unseren Punkt: Sie werden es nie wissen, es sei denn, Sie messen es! performance.now()
eine präzise Ausführungszeit in JavaScript erhalten, stießen wir auf ein Benchmark -Szenario, in dem unsere Intuition genau das Gegenteil der Schlussfolgerungen war, aus denen wir mit unseren empirischen Ergebnissen gekommen sind. Der Punkt ist, dass Ihr JavaScript -Code optimiert werden muss, wenn Sie schnellere Webanwendungen schreiben möchten. Da Computer (fast) Lebewesen sind, sind sie unvorhersehbar und überraschend. Der zuverlässigste Weg zu wissen, dass unsere Codeverbesserungen zu schnelleren Ausführungsgeschwindigkeiten führen, ist die Messung und Vergleich. Wir wissen nie, welcher Code schneller ist, und wenn wir mehrere Möglichkeiten haben, dasselbe zu tun, ist ein weiterer Grund, dass der Kontext wichtig ist. Im vorherigen Abschnitt haben wir eine von Fall unempfindliche String-Suche durchgeführt und nach einer Zeichenfolge in 26 anderen Zeichenfolgen gesucht. Wenn wir nach einer Schnur in 100.000 anderen Saiten suchen müssten, wäre die Schlussfolgerung höchstwahrscheinlich völlig anders. Die obige Liste ist nicht erschöpfend, da mehr Fallstricke zu wissen sind. Zum Beispiel die Messung unpraktischer Szenarien oder nur Messungen an einer JavaScript -Engine. Es ist jedoch sicher, dass performance.now()
ein großes Kapital für JavaScript -Entwickler ist, die schnellere und bessere Webanwendungen schreiben möchten. Denken Sie nicht zuletzt daran, dass die Messung der Ausführungszeit nur eine Dimension von "besserem Code" erzeugt. Speicher- und Codekomplexität müssen ebenfalls berücksichtigt werden. Was ist mit dir? Haben Sie diese Funktion jemals verwendet, um die Leistung Ihres Codes zu testen? Wenn nicht, wie gehen Sie in dieser Phase vor? Bitte teilen Sie Ihre Gedanken in den Kommentaren unten mit. Beginnen wir die Diskussion!
Das obige ist der detaillierte Inhalt vonMessung von JavaScript -Funktionen ' Leistung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!