Die BubbleSort-Funktion ist synchron und es dauert einige Sekunden, bis sie abgeschlossen ist. Siehe Code hier:
Das Ergebnis in der Konsole ist “Ende Sitzung: 0 Sekunden”, da der Intervall-Callback nie aufgerufen wird.
Weißt du, wie ich es anrufen kann? Vielen Dank Jungs!
=+ ist ein ungültiger Operator
– charlietfl
24. Mai 2017 um 12:12 Uhr
Hinweis instance.measureSyncFunc(bubbleSort(array)) Sie passieren die Ergebnis des Anrufs bubbleSort zu Ihrem measureSyncFuncaber measureSyncFunc erwartet eine Funktion als Argument
– Jaromanda X
24. Mai 2017 um 12:12 Uhr
setInterval von 1 ms – ein so kleines Intervall ist eigentlich nicht möglich – haben Sie die heutzutage in den meisten Browsern verfügbaren Profiling-Tools in Betracht gezogen? performance.now() oder console.time('xxx') / console.timeEnd('xxx')
– Jaromanda X
24. Mai 2017 um 12:14 Uhr
@charlietfl invalid operator – eigentlich würde das dazu führen elapsed == 1dauerhaft :p
– Jaromanda X
24. Mai 2017 um 12:17 Uhr
toskv
Wenn die Funktionen, die Sie messen möchten, immer synchron sind, müssen Sie wirklich keine Versprechungen machen.
Da die Funktion, die Sie testen möchten, Parameter benötigt, packen Sie sie am besten in eine Pfeilfunktion, um sie mit einem anderen Kontext aufrufen zu können und ihre Parameter nicht selbst verwalten zu müssen.
Etwas Einfaches wie dieses wird gut tun.
function measure(fn: () => void): number {
let start = performance.now();
fn();
return performance.now() - start;
}
function longRunningFunction(n: number) {
for (let i = 0; i < n; i++) {
console.log(i);
}
}
let duration = measure(() => {
longRunningFunction(100);
});
console.log(`took ${duration} ms`);
Wenn Sie die Zeit messen möchten, die eine asynchrone Funktion (wenn sie ein Versprechen zurückgibt) zum Auflösen benötigt, können Sie den Code einfach in etwa so ändern:
function measurePromise(fn: () => Promise<any>): Promise<number> {
let onPromiseDone = () => performance.now() - start;
let start = performance.now();
return fn().then(onPromiseDone, onPromiseDone);
}
function longPromise(delay: number) {
return new Promise<string>((resolve) => {
setTimeout(() => {
resolve('Done');
}, delay);
});
}
measurePromise(() => longPromise(300))
.then((duration) => {
console.log(`promise took ${duration} ms`);
});
Hinweis: Diese Lösung verwendet den ES6 Versprechenwenn Sie etwas anderes verwenden, müssen Sie es möglicherweise anpassen, aber die Logik sollte dieselbe sein.
Sie können beide Beispiele im Playground sehen hier.
Und wie @JaromandaX in einem Kommentar zu der Frage betonte, besteht die vielleicht wichtigste Änderung darin, die nicht zu bestehen Ergebnis der Langzeitfunktion in die Timing-Funktion.
– TripeHound
24. Mai 2017 um 12:55 Uhr
in der Tat bedeutet dies zumindest für Sync-Funktionen, dass die gesamte Ausführung bereits abgeschlossen ist. Ich werde das als Bemerkung in die Antwort einfügen, wenn es Ihnen nichts ausmacht. 🙂
– toskv
24. Mai 2017 um 12:56 Uhr
Auf jeden Fall (aber der Verdienst geht an @JaromandaX). Wie gut/schlecht der Rest des OP-Codes auch war, er hätte ohne das Lambda-Konstrukt (oder Äquivalent) unmöglich funktionieren können.
– TripeHound
24. Mai 2017 um 13:40 Uhr
normale Funktion würde es auch tun, aber Pfeilfunktionen sind in diesem Fall flexibler.
– toskv
24. Mai 2017 um 13:41 Uhr
Es sollte beachtet werden, dass dieser Ansatz ist nicht zuverlässig wenn mehrere Promises parallel ausgeführt werden – wenn die Promises eine gewisse Menge an Blockierungsarbeit leisten, werden die Ergebnisse mehr oder weniger zufällig sein. Ich habe alle Ansätze in diesem Thread ausprobiert (Stand 13. April 22) und keiner von ihnen funktioniert. Ich glaube nicht, dass es einen zuverlässigen Weg gibt, Versprechen zeitlich festzulegen. Wenn Sie x Promises parallel ausführen, hängt das, was Sie am Ende messen, von der internen Planung ab, und Sie messen letztendlich die Zeit, die das langsamste Promise für alle Promises benötigt.
– mindplay.dk
13. April um 9:29 Uhr
Nicht verwenden setInterval um Millisekunden zu zählen (es ist ungenau, verzögert, driftet und hat ein Mindestintervall von etwa 4 ms). Holen Sie sich einfach zwei Zeitstempel vor und nach der Ausführung.
Die Zielfunktion wird umschlossen und ausgeführt, wenn die umschlossene Funktion aufgerufen wird
Hängt Erfüllungs-/Ablehnungs-Handler an das zugrunde liegende Promise an, das den Rückgabewert der Zielfunktionen als „ret“ und die verstrichene Zeit als „elapsedTime“ zurückgibt.
unterstützt Argumente, indem es sie an die Zielfunktion weiterleitet
Hier ist eine einfache Wrapper-Funktion, die ich geschrieben habe. Es gibt ein Promise (über das Schlüsselwort async) zurück, sodass Sie es einfach mit Ihrem Promise aufrufen können. Ich habe den Zeitwert als Eigenschaft zur Antwort hinzugefügt. Wenn Sie diesen Wert nicht in der Antwort haben können, müssen Sie ihn anschließend entfernen.
Es wäre gut klarzustellen, dass die vorgeschlagenen Ansätze von toskv nur mit der Auflösung eines einzigen Versprechens funktionieren. Wenn wir Promise.all() verwenden wollen, ist das zurückgegebene Zeitergebnis falsch.
Hier ist ein Beispiel mit dem von toskv entwickelten Code, aber mit Promise.all()
Wenn jemand die Zeit messen muss, die benötigt wird, um jedes der mit Promise.all() ausgeführten Versprechen auszuführen, besteht der Ansatz darin, die Interzeptoren zu verwenden und dort die Zeitmessungen durchzuführen
10160300cookie-checkWie misst man die Ausführungszeit eines Versprechens?yes
=+
ist ein ungültiger Operator– charlietfl
24. Mai 2017 um 12:12 Uhr
Hinweis
instance.measureSyncFunc(bubbleSort(array))
Sie passieren die Ergebnis des Anrufs bubbleSort zu IhremmeasureSyncFunc
abermeasureSyncFunc
erwartet eine Funktion als Argument– Jaromanda X
24. Mai 2017 um 12:12 Uhr
setInterval
von 1 ms – ein so kleines Intervall ist eigentlich nicht möglich – haben Sie die heutzutage in den meisten Browsern verfügbaren Profiling-Tools in Betracht gezogen?performance.now()
oderconsole.time('xxx') / console.timeEnd('xxx')
– Jaromanda X
24. Mai 2017 um 12:14 Uhr
@charlietfl
invalid operator
– eigentlich würde das dazu führenelapsed == 1
dauerhaft :p– Jaromanda X
24. Mai 2017 um 12:17 Uhr