Gibt es in JavaScript Timing-Funktionen mit einer Auflösung von Mikrosekunden?
Ich kenne timer.js für Chrome und hoffe, dass es eine Lösung für andere benutzerfreundliche Browser wie Firefox, Safari, Opera, Epiphany, Konqueror usw. gibt. Ich bin nicht daran interessiert, einen IE zu unterstützen, sondern Antworten einschließlich IE sind willkommen.
(Angesichts der schlechten Genauigkeit des Millisekunden-Timings in JS halte ich bei diesem nicht den Atem an!)
Update: timer.js kündigt eine Mikrosekundenauflösung an, multipliziert jedoch einfach den Millisekundenwert mit 1.000. Verifiziert durch Testen und Code-Inspektion. Enttäuscht. : [
javascript
mwcz
quelle
quelle
Antworten:
Wie in Mark Rejhons Antwort erwähnt, ist in modernen Browsern eine API verfügbar, die Timing-Daten mit einer Auflösung von weniger als einer Millisekunde für Skripte verfügbar macht: der W3C High Resolution Timer , auch bekannt als
window.performance.now()
.now()
istDate.getTime()
in zweierlei Hinsicht besser als das Traditionelle :now()
ist ein Double mit einer Auflösung von Submillisekunden, das die Anzahl der Millisekunden seit Beginn der Seitennavigation darstellt. Es gibt die Anzahl der Mikrosekunden im Bruchteil zurück (z. B. ein Wert von 1000,123 ist 1 Sekunde und 123 Mikrosekunden).now()
nimmt monoton zu. Dies ist wichtig, da es bei nachfolgenden Anrufen möglicherweise vorwärts oder sogar rückwärts springenDate.getTime()
kann . Insbesondere wenn die Systemzeit des Betriebssystems aktualisiert wird (z. B. Atomuhrsynchronisation), wird dies ebenfalls aktualisiert. wird garantiert immer monoton ansteigen, so dass es nicht von der Systemzeit des Betriebssystems beeinflusst wird - es wird immer die Wanduhrzeit sein (vorausgesetzt, Ihre Wanduhr ist nicht atomar ...).Date.getTime()
now()
now()
kann an fast jedem Ort verwendet werdennew Date.getTime()
,+ new Date
undDate.now()
sind. Die Ausnahme ist , dassDate
undnow()
mal nicht mische, daDate
auf Basis Unix-Epoche (die Anzahl der Millisekunden seit 1970), währendnow()
die Anzahl der Millisekunden seit Ihrer Seite der Navigation gestartet (so ist es viel kleiner als seinDate
).now()
wird in Chrome Stable, Firefox 15+ und IE10 unterstützt. Es gibt auch mehrere Polyfills .quelle
new Date.getTime()
ist keine Sache.new Date().getTime()
ist.console.log
bei jedem Lauf etwas so Teueres wie eine gemacht habe. ) Schwer zu erkennen, aber kopieren Sie den gesamten hervorgehobenen Code hier:last=-11; same=0; runs=100; for(let i=0;i<runs;i++) { let now = performance.now(); console.log('.'); if (now === last) { same++; } last = now; } console.log(same, 'were the same');
Es gibt jetzt eine neue Methode zum Messen von Mikrosekunden in Javascript: http://gent.ilcore.com/2012/06/better-timer-for-javascript.html
In der Vergangenheit habe ich jedoch eine grobe Methode gefunden, um aus einem Millisekunden-Timer eine Genauigkeit von 0,1 Millisekunden in JavaScript zu erhalten. Unmöglich? Nee. Weiter lesen:
Ich mache einige hochpräzise Experimente, die selbst überprüfte Timergenauigkeiten erfordern, und habe festgestellt, dass ich mit bestimmten Browsern auf bestimmten Systemen zuverlässig eine Genauigkeit von 0,1 Millisekunden erzielen konnte.
Ich habe festgestellt, dass in modernen GPU-beschleunigten Webbrowsern auf schnellen Systemen (z. B. i7 Quad Core, wo mehrere Kerne inaktiv sind, nur Browserfenster) - ich kann jetzt darauf vertrauen, dass die Timer millisekundengenau sind. Tatsächlich ist es auf einem i7-System im Leerlauf so genau geworden, dass ich über mehr als 1.000 Versuche zuverlässig genau dieselbe Millisekunde erhalten konnte. Nur wenn ich versuche, eine zusätzliche Webseite oder eine andere zu laden, verschlechtert sich die Millisekundengenauigkeit (und ich kann meine eigene verschlechterte Genauigkeit erfolgreich erfassen, indem ich eine Vorher-Nachher-Zeitprüfung durchführe, um festzustellen, ob Meine Verarbeitungszeit verlängerte sich plötzlich auf 1 oder mehr Millisekunden - dies hilft mir, Ergebnisse ungültig zu machen, die wahrscheinlich zu stark durch CPU-Schwankungen beeinträchtigt wurden.
Es ist in einigen GPU-beschleunigten Browsern auf i7 Quad-Core-Systemen so genau geworden (wenn das Browserfenster das einzige Fenster ist), dass ich mir gewünscht habe, ich könnte auf einen 0,1-ms-Präzisions-Timer in JavaScript zugreifen, da die Genauigkeit jetzt endlich ist Es gibt einige High-End-Browsersysteme, mit denen sich eine solche Timer-Präzision für bestimmte Arten von Nischenanwendungen lohnt, die eine hohe Präzision erfordern und bei denen die Anwendungen in der Lage sind, sich auf Genauigkeitsabweichungen zu überprüfen.
Wenn Sie mehrere Durchgänge ausführen, können Sie natürlich einfach mehrere Durchgänge ausführen (z. B. 10 Durchgänge) und dann durch 10 dividieren, um eine Genauigkeit von 0,1 Millisekunden zu erhalten. Dies ist eine gängige Methode, um eine bessere Präzision zu erzielen. Führen Sie mehrere Durchgänge durch und teilen Sie die Gesamtzeit durch die Anzahl der Durchgänge.
JEDOCH ... Wenn ich aufgrund einer ungewöhnlich einzigartigen Situation nur einen einzigen Benchmark-Durchgang eines bestimmten Tests durchführen kann, habe ich festgestellt, dass ich auf diese Weise eine Genauigkeit von 0,1 (und manchmal 0,01 ms) erreichen kann:
Initialisierung / Kalibrierung:
Benchmarking eines Durchgangs mit einer Genauigkeit von weniger als einer Millisekunde:
WARNUNG: Busy-Loops werden in Webbrowsern NICHT empfohlen. Glücklicherweise werden diese Busy-Loops jeweils weniger als 1 Millisekunde lang ausgeführt und nur sehr wenige Male ausgeführt.
Variablen wie die JIT-Kompilierung und CPU-Schwankungen führen zu massiven Ungenauigkeiten. Wenn Sie jedoch mehrere Initialisierungsdurchläufe ausführen, erhalten Sie eine vollständige dynamische Neukompilierung, und schließlich wird der Zähler auf etwas sehr Genaues eingestellt. Stellen Sie sicher, dass alle Besetztschleifen in allen Fällen genau dieselbe Funktion haben, damit Unterschiede in Besetztschleifen nicht zu Unterschieden führen. Stellen Sie sicher, dass alle Codezeilen mehrmals ausgeführt werden, bevor Sie den Ergebnissen vertrauen, damit sich JIT-Compiler bereits zu einer vollständigen dynamischen Neukompilierung (Dynarec) stabilisiert haben.
Tatsächlich habe ich auf bestimmten Systemen eine Präzision gesehen, die sich Mikrosekunden nähert , aber ich würde ihr noch nicht vertrauen. Aber die Genauigkeit von 0,1 Millisekunden scheint auf einem inaktiven Quad-Core-System, auf dem ich die einzige Browserseite bin, ziemlich zuverlässig zu funktionieren. Ich kam zu einem wissenschaftlichen Testfall, in dem ich nur einmalige Durchgänge durchführen konnte (aufgrund eindeutiger Variablen), und musste jeden Durchgang genau zeitlich festlegen, anstatt mehrere Wiederholungsdurchläufe zu mitteln. Deshalb habe ich dies getan.
Ich habe mehrere Pre-Pässe und Dummy-Pässe durchgeführt (auch um den Dynarec zu regeln), um die Zuverlässigkeit mit einer Genauigkeit von 0,1 ms zu überprüfen (blieb einige Sekunden lang solide), dann habe ich meine Hände von der Tastatur / Maus gelassen, während der Benchmark stattfand, und dann mehrere Nachdurchläufe zur Überprüfung der Zuverlässigkeit mit einer Genauigkeit von 0,1 ms (blieb wieder solide). Dies stellt auch sicher, dass Dinge wie Änderungen des Energiezustands oder andere Dinge zwischen dem Vorher und Nachher nicht aufgetreten sind und die Ergebnisse beeinträchtigen. Wiederholen Sie den Vor- und Nach-Test zwischen jedem einzelnen Benchmark-Durchgang. In diesem Zusammenhang war ich mir ziemlich sicher, dass die dazwischen liegenden Ergebnisse korrekt waren. Es gibt natürlich keine Garantie, aber es zeigt, dass in einem Webbrowser in einigen Fällen eine Genauigkeit von <0,1 ms möglich ist .
Diese Methode ist nur in sehr, sehr Nischenfällen nützlich . Trotzdem ist es buchstäblich nicht 100% ig garantiert, Sie können eine sehr vertrauenswürdige Genauigkeit und sogar wissenschaftliche Genauigkeit erzielen, wenn Sie es mit mehreren Ebenen interner und externer Überprüfungen kombinieren.
quelle
Date.now()
oder hatten+new Date()
. Aber jetzt haben wirperformance.now()
. Obwohl es klar ist, dass Sie einige coole Möglichkeiten gefunden haben, mehr Funktionen zu hacken, ist diese Antwort im Wesentlichen veraltet. Empfehlen Sie auch nichts im Zusammenhang mit Besetztschleifen. Tu das einfach nicht. Mehr brauchen wir nicht.Die Antwort lautet im Allgemeinen "Nein". Wenn Sie JavaScript in einer serverseitigen Umgebung verwenden (dh nicht in einem Browser), sind alle Wetten deaktiviert und Sie können versuchen, alles zu tun, was Sie wollen.
bearbeiten - diese Antwort ist alt; Die Standards wurden weiterentwickelt und neuere Einrichtungen stehen als Lösungen für das Problem der genauen Zeit zur Verfügung. Es sollte jedoch beachtet werden, dass gewöhnlicher nicht privilegierter Code außerhalb der Domäne eines echten Echtzeitbetriebssystems nur begrenzte Kontrolle über seinen Zugriff auf Rechenressourcen hat. Das Messen der Leistung ist nicht dasselbe (notwendigerweise) wie das Vorhersagen der Leistung.
quelle
Hier ist ein Beispiel, das meinen hochauflösenden Timer für node.js zeigt :
Verwendung:
Normalerweise können Sie möglicherweise Folgendes verwenden:
Wenn Sie Codeabschnitte zeitlich festlegen, die eine Schleife beinhalten, können Sie nicht auf den Wert von zugreifen
console.timeEnd()
, um Ihre Timer-Ergebnisse zu addieren. Sie können, aber es wird unangenehm, weil Sie den Wert Ihrer iterierenden Variablen einfügen müssen, z. B.i
, und eine Bedingung festlegen müssen, um festzustellen, ob die Schleife abgeschlossen ist.Hier ist ein Beispiel, weil es nützlich sein kann:
Zitieren: https://nodejs.org/api/process.html#process_process_hrtime_time
quelle