CPU-Lastdifferenz zwischen vier ähnlichen Javascript-Funktionen messen

8

Warum ist das wichtig für mich

?

Ich habe eine Seite, auf der ich einen Countdown-Timer laufen lassen muss, um den Leuten zu zeigen, wie viel Zeit sie noch haben, um eine Aktion abzuschließen.

Dieser Timer wird Tage lang laufen und wahrscheinlich nur MomentJS verwenden, um etwas wie "in 4 Tagen" aus der Funktion to() von MomentJS zu sagen.

Wenn wir noch eine Stunde Zeit haben, werde ich zu einem Countdown nach Minuten wechseln, und wenn die Minuten niedrig genug sind, werde ich einen Sekundentimer haben. Wenn wir zu den letzten paar Minuten kommen, werde ich sogar Millisekunden anzeigen.

Das Problem

So ziemlich gibt es zwei Haupttechniken, um den Countdown-Timer zu animieren.

  • setInterval()
  • requestAnimationFrame()

Nun, ich habe gleich bemerkt, dass die requestAnimationFrame() -Methode viel flüssiger für das Auge ist, es funktioniert großartig - besonders wenn ich Millisekunden zeige. Es dauerte jedoch nicht lange, bis ich bemerkte, dass mein armer Computer ein wenig warm wurde. All diese "Animation" verursacht eine ziemlich große Belastung für meine CPU. Ich habe versucht, CPU-Monitore zu verwenden, und habe mich nach Wegen umgesehen, um zu sehen, wie viel diese Belastung auf meine CPU wirkt, aber insgesamt kann ich kein Tool finden, das mir eine klare Grafik zeigt, welche Art von CPU-Last mein kleiner Countdown-Timer ist verwenden.

Also habe ich beschlossen, einen Weg zu finden, den FPS zu begrenzen und zu sehen, ob das mein Problem reduzieren würde. Und ja, tut es. Wenn Sie setTimeout() zusammen mit requestAnimationFrame() verwenden, können Sie eine Wartezeit festlegen, bevor Sie Ihre nächste Funktion aufrufen.

Was die Frage aufwirft, wenn Sie setTimeout() verwenden - Warum benutzen Sie nicht einfach setInterval() und vergessen die zusätzliche Optimierung, die Ihnen requestAnimationFrame() bietet?

Ich habe mich etwas umgeschaut und eine andere Methode gefunden, die einfach überprüft, ob die richtige Menge an Intervallzeit seit dem letzten Aufruf von requestAnimationFrame() vergangen ist. Ich habe einige Optimierungen vorgenommen, wie dieser Code funktioniert und endete mit einer der beiden Funktionen, die ich unten messen möchte.

Am Ende möchte ich einen eindeutigeren Weg haben, dies zu messen - denn der Aktivitätsmonitor auf meinem Mac ist kaum ein zuverlässiges Werkzeug, um genau zu lesen - und ich finde keinen Weg, um genau zu messen der Code, den ich verwende.

Chrome hat einige weitere Werkzeuge, den Profiler und die Zeitleiste - die beide sehr hilfreich sind, aber sie geben mir nicht die Metrik, nach der ich suche - CPU-Last.

Der Code:

Hier sind vier Code-Snippets, die genau dasselbe tun - alle benutzen:

  • MomentJS
  • CountdownJS
  • jQuery

Der Code ist 100% identisch, der einzige Unterschied ist, wie ich den FPS der Animation begrenze.

Ich würde gerne einen Weg finden, um den Unterschied zwischen den vier Funktionen bei der CPU-Last so genau wie möglich zu messen. Und dann würde ich gerne den FPS ändern, um zu sehen, ob ich eine akzeptable Last für meine Anwendung finde und dann kann ich den Sweet Spot finden - die richtige Menge an FPS während der verschiedenen Timer-Phasen.

Technik 1 - setTimeout ()

%Vor% %Vor%

Technik 2 - Delta zwischen den Intervallen

%Vor% %Vor%

Technik 3 - setInterval ()

%Vor% %Vor%

Es wäre auch interessant, eine völlig ungedrosselte Version wie folgt zu sehen:

Technik 4 - Kein Gas

%Vor% %Vor%

Einfach ausgedrückt: Wie misst man den CPU-Lastunterschied zwischen vier ähnlichen JavaScript-Funktionen?

Weiß jemand schon, welcher von diesen mehr performant sein wird? (Ich weiß, das ist nicht wirklich ein Wort)

    
Jeremy Iglehart 25.06.2016, 02:06
quelle

1 Antwort

2

Beantworte meine eigene Frage:

Die kurze Antwort:

  • Schlechteste Leistung

      

    Offensichtlich setInterval() ist die schlechteste Lösung. Weil setInterval() immer noch läuft, während Sie nicht auf der Registerkarte sind, verschwenden CPU und damit Akkulaufzeit.

  • Beste Animation (Mikrosekunden)

      

    Offensichtlich ist die Berechnungsmethode Delta Interval Math die einfachste und genaueste Methode zur Berechnung der Intervallzeit. Wenn Sie diesen Algorithmus mit der Genauigkeit der Berechnung von Rahmenzeiten mit performance.now() kombinieren, können Sie Ergebnisse genau in Mikrosekunden mit Ihren Animationsrahmen erzielen.

         

    (und ja, auch requestAnimationFrame() verwendet performance.now() time als erstes Argument, das an die Callback-Funktion übergeben wird) .

         

    Und ja Leute, ich meine wirklich Mikrosekunden. Das ist 1s / 1000ms / 1000μs.

         

    Mach weiter, teste es jetzt. Öffne deine Konsole und tippe: performance.now() Und du bekommst eine Zahl, die aussieht wie 2132438.165 - das sind Millisekunden, seit der Browser den ersten Frame gerendert hat.

         

    (Das ist besonders cool, weil μ ein griechisches Zeichen +10 nerd points ist)

  • Beste CPU-Leistung (Millisekunden)

      

    Kombinieren Sie requestAnimationFrame() (wodurch Ihre Animation beim Wechseln zwischen Tabs in den Ruhezustand versetzt wird) mit setTimeout() , wodurch der FPS Ihrer Animation auf ein beliebiges Millisekundenintervall gedrosselt werden kann.

         

    Beachten Sie jedoch, dass der Unterschied zwischen dieser Methode und der Delta Interval Math -Methode sehr leicht unterschiedlich ist. Ich habe nicht einmal eine Möglichkeit zu quantifizieren, wie klein der Unterschied ist. Von dem, was ich sagen kann, könnte es ein Viertel bis ein Achtel effizienter sein. Aber du verlierst eine Menge Glätte dafür. Ihre Wahl.

Die lange Antwort:

Ich freue mich immer noch auf eine bessere Möglichkeit, dies zu tun, vielleicht auf eine Weise, die es mir erlaubt, Daten zwischen verschiedenen Funktionen zu vergleichen.

Bis dahin konnte ich diese Bilder mithilfe von Google's Javascript erstellen CPU-Profiler

Auflistung in der Reihenfolge, in der ich glaube, dass sie performant sind, aber mit Titeln, die der ursprünglichen Frage entsprechen:

Technik 3 - setInterval ()

Technik 1 - setTimeout ()

Technik 2 - Delta zwischen den Intervallen

Technik 4 - Kein Gas geben

Visuelle Analyse

Nun, nach dem Aussehen würde ich die verschiedenen Funktionen in dieser Reihenfolge der Leistung ordnen:

  1. setInterval() function.
  2. setTimeout() wrapping the requestAnimationFrame () 'call.
  3. Delta-Intervall-Mathematik innerhalb der rekursiven Funktion, die von requestAnimationFrame() aufgerufen wird
  4. Kein FPS Throttle wird einfach mit requestAnimationFrame() durchlaufen

Fazit: [Bearbeitet: 25.06.2016]

Die setInterval() -Funktion ist besser als jedes requestAnimationFrame() -Muster, das ich zumindest für CPU-Nutzungsgründe gefunden habe NUR WÄHREND SIE AUF DEM TAB sind.

Wenn also CPU-Kosten oder die größte Sorge für Ihre Anwendung sind, dann gehen Sie mit requestAnimationFrame() und drosseln Sie den FPS mit:

  • Die setTimeout() -Methode, die ein wenig weniger für die CPU funktioniert (das Beste aus beiden Welten) - aber zugegebenermaßen weniger flüssig als die Methode unten.
  • oder
  • Die Delta Interval Math , die eine Animation etwas glatter erscheinen lässt (Und die Technik-Umrisse in dieser Frage / Antwort mit der Zeit von performance.now() und der Zeit, die von requestAnimationFrame() gemeldet wird, verwendet das aktuelle performance.now() , das im ersten Argument der Callback-Funktion bereitgestellt wird. Weil wir den genauesten Algorithmus verwenden, den ich gesehen habe, um den Animationsrahmen zu berechnen (Sie berechnen tatsächlich bis auf eine Millionstel Sekunde oder a Mikrosekunden 1s / 1000ms / 1000μs) Es gibt keinen RIESIGEN Unterschied in der CPU-Last von dieser Technik und setTimeout() - aber es gibt einen Unterschied (siehe die beigefügten Bilder)

Warum ist requestAnimationFrame() die Bombendigitalität? - Denn: Wenn Sie nicht auf dieser Registerkarte sind, wird sie vom Browser deaktiviert Deine Animationen warten darauf, dass du zurückkommst. UND mit performance.now () erreichst du Mikrosekunden (μs) Genauigkeit in deiner Animation.

Es wird gesagt, dass requestAnimationFrame() eine" optimierte "Methode ist, um sicherzustellen, dass Ihre Animation zusammen mit anderen Browsern funktioniert, so dass Ihre Animation" passt "mit dem, was der Browser macht, kommt es auch bei einem 60FPS Callback Kosten.

Schritte, die ich gemacht habe, um diese Fotos zu erstellen:

  1. Ich habe einzelne leere HTML-Dateien erstellt, mit nichts als absolutem, was ich für die Tests benötigt habe.
  2. Ich habe meinen Computer neu gestartet und nur meinen Chrome-Browser auf einem about:blank Tab geöffnet.
  3. Jede "test benchmark" HTML-Datei wurde geöffnet, die ich zuvor einzeln und einzeln erstellt habe.
  4. Genau in 50 Sekunden nach dem Countdown-Zähler klickte ich start auf Googles Javascript CPU Profiler und genau 10 Sekunden später habe ich auf stop geklickt (ich habe ein spezielles Klick-Makro in meinem Gamer-Maus spezielle Treiber-Software , die ziemlich gut funktioniert - Sobald ich auf den Knopf klicke Es klickt start und 10 Sekunden später ein weiterer Klick auf stop - gut genug für diese Fotos)
  5. Gespeichert das Profil auf meinem Computer
  6. Alle Profile wurden in das Profiler-Tool auf der Registerkarte about:blank geladen.
  7. Die Größe des Fensters wurde geändert, um die Daten gut zu umrahmen
  8. Screenshot [shift] + [cmd] + [4] und dann drückst du space auf der Tastatur, um den Screenshot genau um das Fenster zu legen.

Ungelöstes Problem:

Ich habe immer noch keine Möglichkeit zu sehen, wie der CPU-Verbrauch ist. Diese Grafik lässt mich etwas detaillierter sehen. Die anderen Google Javascript CPU Profiler -Bildschirme sind ebenfalls etwas vage in diesem Sinne. Vielleicht weiß ich einfach nicht, wie man das Werkzeug benutzt.

Wenn jemand einen besseren Benchmark für das Testen weiß, bitte senden Sie eine Antwort und ich werde es überprüfen. Ich hoffe es ist besser als dieses Durcheinander. Und danke im Voraus.

Das Hauptproblem besteht darin, harte Daten von einem CPU-Profil zu einem anderen zu quantifizieren und zu vergleichen. Das ist es, was ich am meisten vermisse.

    
Jeremy Iglehart 25.06.2016 06:55
quelle