it-swarm.com.de

Intelligente Fortschrittsanzeige ETA-Berechnung

In vielen Anwendungen verfügen wir über einen Fortschrittsbalken für das Herunterladen von Dateien, für eine Komprimierungsaufgabe, für eine Suche usw. Wir alle verwenden häufig Fortschrittsbalken, um Benutzer darauf aufmerksam zu machen, dass etwas passiert. Und wenn wir wissen, wie viel Arbeit bereits geleistet wurde und wie viel noch zu tun ist, können wir sogar eine Zeitschätzung abgeben, indem wir häufig die Zeit extrapolieren, die erforderlich ist, um das aktuelle Fortschrittsniveau zu erreichen.

ETA-Screenshot zur Komprimierung http://jameslao.com/wp-content/uploads/2008/01/winrar-progress-bar.png

Wir haben aber auch Programme gesehen, die dieses Time Left "ETA" -Display nur komisch schlecht finden. Es wird behauptet, dass eine Dateikopie in 20 Sekunden erstellt wird. Eine Sekunde später wird angegeben, dass es 4 Tage dauern wird. Dann flackert es erneut und beträgt 20 Minuten. Es ist nicht nur wenig hilfreich, es ist auch verwirrend! Der Grund, warum die ETA so unterschiedlich ist, ist, dass die Fortschrittsrate selbst variieren kann und die Mathematik des Programmierers übermäßig empfindlich sein kann.

Apple umgeht dies, indem es nur genaue Vorhersagen vermeidet und nur vage Schätzungen macht! Apples vage Umgehung http://download.autodesk.com/esd/mudbox/help2009/images/MED/DaliSP1/English/Install_licensing/install_progress_MAC.png

Das ist auch ärgerlich. Habe ich Zeit für eine kurze Pause oder ist meine Aufgabe in 2 Sekunden erledigt? Wenn die Vorhersage zu unscharf ist, ist es sinnlos, überhaupt eine Vorhersage zu treffen.

Einfache aber falsche Methoden

Bei einer ETA-Berechnung im ersten Durchgang erstellen wir wahrscheinlich alle nur eine Funktion, bei der p der bereits durchgeführte Prozentsatz ist und t die bisher benötigte Zeit ist, und wir geben t * (1-p)/p als Schätzung von aus wie lange es dauern wird, bis es fertig ist. Dieses einfache Verhältnis funktioniert "OK", aber es ist auch besonders am Ende der Berechnung schrecklich. Wenn Ihre langsame Download-Geschwindigkeit eine Kopie über Nacht langsam voranbringt und schließlich morgens etwas eintritt und die Kopie mit 100-mal schnellerer Geschwindigkeit beginnt, kann Ihre ETA bei 90% fertig "1 Stunde" und 10 Sekunden sagen später sind Sie bei 95% und die ETA sagt "30 Minuten", was eindeutig eine peinlich schlechte Schätzung ist. In diesem Fall ist "10 Sekunden" eine viel, viel, viel bessere Schätzung.

In diesem Fall können Sie die Berechnung ändern, um recent speed, nicht average speed, zur Schätzung der ETA zu verwenden. Sie ermitteln die durchschnittliche Download- oder Abschlussrate in den letzten 10 Sekunden und projizieren anhand dieser Rate, wie lange der Abschluss dauern wird. Dies ist im vorherigen Beispiel für den Download über Nacht, das sich am Ende beschleunigt, recht gut gelungen, da es am Ende sehr gute Schätzungen für die endgültige Fertigstellung geben wird. Dies hat jedoch immer noch große Probleme. Es führt dazu, dass Ihre ETA stark springt, wenn sich Ihre Rate über einen kurzen Zeitraum schnell ändert und Sie das Ergebnis in 20 Sekunden, in 2 Stunden, in 2 Sekunden und in 30 Sekunden erzielen Minuten "schnelle Anzeige der Programmierschande.

Die eigentliche Frage:

Was ist der beste Weg, um eine geschätzte Fertigstellungszeit einer Aufgabe zu berechnen, wenn man den zeitlichen Verlauf der Berechnung berücksichtigt? Ich suche keine Links zu GUI-Toolkits oder Qt-Bibliotheken. Ich frage nach dem Algorithmus , um die vernünftigsten und genauesten Schätzungen für die Fertigstellungszeit zu generieren.

Hattest du Erfolg mit mathematischen Formeln? Eine Art von Mittelwertbildung, vielleicht mit dem Mittelwert der Rate über 10 Sekunden und der Rate über 1 Minute und der Rate über 1 Stunde? Eine künstliche Filterung wie "Wenn meine neue Schätzung zu stark von der vorherigen Schätzung abweicht, verringern Sie sie, lassen Sie sie nicht zu stark abprallen"? Eine Art ausgefallene Verlaufsanalyse, bei der Sie Fortschritt über Zeitfortschritt integrieren, um die Standardabweichung der Rate zu ermitteln und nach Abschluss statistische Fehlermetriken zu erhalten?

Was haben Sie versucht und was funktioniert am besten?

67
SPWorley

Ursprüngliche Antwort

Das Unternehmen, das diese Site erstellt hat anscheinend ein Planungssystem, das diese Frage im Zusammenhang mit dem Schreiben von Code durch Mitarbeiter beantwortet. Die Art und Weise, wie es funktioniert, ist mit der Monte-Carlo-Simulation der Zukunft basierend auf der Vergangenheit.

Anhang: Erklärung von Monte Carlo

So würde dieser Algorithmus in Ihrer Situation funktionieren:

Sie modellieren Ihre Aufgabe als eine Folge von Mikrotasks, beispielsweise 1000 von ihnen. Angenommen, Sie haben eine Stunde später 100 davon abgeschlossen. Jetzt führen Sie die Simulation für die verbleibenden 900 Schritte durch, indem Sie 90 abgeschlossene Mikrotasks zufällig auswählen, ihre Zeiten hinzufügen und mit 10 multiplizieren. Hier haben Sie eine Schätzung; N-mal wiederholen und Sie haben N Schätzungen für die verbleibende Zeit. Beachten Sie, dass der Durchschnitt zwischen diesen Schätzungen bei 9 Stunden liegen wird - hier keine Überraschungen. Indem Sie dem Benutzer die resultierende Verteilung präsentieren, teilen Sie ihm ehrlich die Gewinnchancen mit, z. "Mit einer Wahrscheinlichkeit von 90% wird dies weitere 3-15 Stunden dauern."

Dieser Algorithmus liefert per Definition ein vollständiges Ergebnis, wenn die betreffende Aufgabe als eine Gruppe von Aufgaben modelliert werden kann unabhängig, zufällig Mikrotasks. Eine bessere Antwort erhalten Sie nur, wenn Sie wissen, wie die Aufgabe von diesem Modell abweicht: Beispielsweise haben Installateure in der Regel eine Jobliste zum Herunterladen/Entpacken/Installieren, und die Geschwindigkeit für das eine kann die andere nicht vorhersagen.

Anhang: Vereinfachung von Monte Carlo

Ich bin kein Statistik-Guru, aber ich denke, wenn Sie sich die Simulation in dieser Methode genauer ansehen, gibt sie immer eine Normalverteilung als Summe einer großen Anzahl unabhängiger Zufallsvariablen zurück. Daher müssen Sie es überhaupt nicht ausführen. Tatsächlich müssen Sie nicht einmal alle abgeschlossenen Zeiten speichern, da Sie nur deren Summe und Summe der Quadrate benötigen.

In vielleicht nicht sehr Standardnotation,

sigma = sqrt ( sum_of_times_squared-sum_of_times^2 )
scaling = 900/100          // that is (totalSteps - elapsedSteps) / elapsedSteps
lowerBound = sum_of_times*scaling - 3*sigma*sqrt(scaling)
upperBound = sum_of_times*scaling + 3*sigma*sqrt(scaling)

Mit dieser Option können Sie die Meldung ausgeben, dass das Objekt mit einer festgelegten Wahrscheinlichkeit von jetzt an zwischen [Untergrenze, Obergrenze] enden wird (sollte etwa 95% betragen, aber ich habe wahrscheinlich einen konstanten Faktor übersehen).

31
ilya n.

Folgendes habe ich für gut befunden! Für die ersten 50% der Aufgabe nehmen Sie an, dass die Rate konstant und extrapoliert ist. Die Zeitvorhersage ist sehr stabil und prallt nicht viel ab.

Sobald Sie 50% überschritten haben, switch berechnen Sie die Strategie. Sie nehmen den verbleibenden Teil der zu erledigenden Aufgabe (1-p), blicken dann in die Vergangenheit Ihres eigenen Fortschritts und ermitteln (durch binäre Suche und lineare Interpolation), wie lange Sie für die letzte Aufgabe gebraucht haben (1 -p) Prozentsatz und benutze dass als Abschluss deiner Zeitschätzung.

Wenn Sie nun zu 71% fertig sind, sind noch 29% übrig. Sie blicken in Ihre Geschichte zurück und stellen fest, wie lange es her ist, dass Sie (71-29 = 42%) fertig sind. Melden Sie diese Zeit als Ihre ETA.

Das ist natürlich anpassungsfähig. Wenn Sie X Arbeit zu erledigen haben, wird nur die Zeit angezeigt, die für die Ausführung der X Arbeit benötigt wurde. Wenn Sie zu 99% fertig sind, werden nur noch sehr aktuelle Daten für die Schätzung verwendet.

Es ist natürlich nicht perfekt, aber es ändert sich reibungslos und ist am Ende besonders genau, wenn es am nützlichsten ist.

13
SPWorley

Normalerweise verwende ich ein Exponential Moving Average , um die Geschwindigkeit einer Operation mit einem Glättungsfaktor von beispielsweise 0,1 zu berechnen und benutze diesen, um die verbleibende Zeit zu berechnen. Auf diese Weise haben alle gemessenen Geschwindigkeiten einen Einfluss auf die aktuelle Geschwindigkeit, aber die jüngsten Messungen haben eine viel größere Auswirkung als die in der fernen Vergangenheit.

Im Code würde es ungefähr so ​​aussehen:

alpha = 0.1 # smoothing factor
...
speed = (speed * (1 - alpha)) + (currentSpeed * alpha)

Wenn Ihre Aufgaben eine einheitliche Größe haben, ist currentSpeed einfach die Zeit, die zur Ausführung der letzten Aufgabe benötigt wurde. Wenn die Aufgaben unterschiedlich groß sind und Sie wissen, dass eine Aufgabe doppelt so lang sein soll wie eine andere, können Sie die zur Ausführung der Aufgabe benötigte Zeit durch ihre relative Größe teilen, um die aktuelle Geschwindigkeit zu ermitteln. Mit speed können Sie die verbleibende Zeit berechnen, indem Sie sie mit der Gesamtgröße der verbleibenden Aufgaben multiplizieren (oder einfach mit ihrer Anzahl, wenn die Aufgaben einheitlich sind).

Hoffentlich ist meine Erklärung klar genug, es ist ein bisschen spät am Tag.

8
gooli

Obwohl alle Beispiele gültig sind, hielt ich es für eine gute Idee, vorhandene Open-Source-Projekte zu betrachten, um zu sehen, was sie bewirken.

Nach allem, was ich sehe, kann Mozilla Firefox die verbleibende Zeit am besten abschätzen.

Mozilla Firefox

Firefox protokolliert die letzte Schätzung der verbleibenden Zeit und führt anhand dieser und der aktuellen Schätzung der verbleibenden Zeit eine Glättungsfunktion für die Zeit durch. Siehe den ETA-Code hier . Dies verwendet eine 'Geschwindigkeit', die vorher berechnet wurde hier und ein geglätteter Durchschnitt der letzten 10 Messwerte ist.

Dies ist ein wenig komplex, um es so zu umschreiben:

  • Ermitteln Sie einen geglätteten Durchschnitt der Geschwindigkeit basierend auf 90% der vorherigen Geschwindigkeit und 10% der neuen Geschwindigkeit.
  • Berechnen Sie mit dieser geglätteten Durchschnittsgeschwindigkeit die geschätzte verbleibende Zeit.
  • Verwenden Sie diese geschätzte verbleibende Zeit und die vorherige geschätzte verbleibende Zeit, um eine neue geschätzte verbleibende Zeit zu erstellen (um ein Springen zu vermeiden).

Google Chrome

Chrome scheint überall herumzuspringen, und der Code zeigt dies .

Eine Sache, die ich mit Chrome mag, ist, wie sie die verbleibende Zeit formatieren. Für> 1 Stunde steht "1 Std. Übrig". Für <1 Stunde steht "59 Min. Übrig". Für <1 Minute steht "52 Sek. Übrig".

Sie können sehen, wie es formatiert ist hier

DownThemAll! Manager

Es benutzt nichts Schlaues, was bedeutet, dass die ETA überall herumspringt.

Siehe den Code hier

pySmartDL (ein Python-Downloader)

Ermittelt die durchschnittliche ETA der letzten 30 ETA-Berechnungen. Klingt nach einer vernünftigen Methode.

Sehen Sie den Code hier / blob/916f2592db326241a2bf4d8f2e0719c58b71e385/pySmartDL/pySmartDL.py # L651)

Übertragung

Gibt in den meisten Fällen eine ziemlich gute ETA (außer zu Beginn, wie zu erwarten).

Verwendet einen Glättungsfaktor in den letzten 5 Messwerten, ähnlich wie Firefox, jedoch nicht ganz so komplex. Grundsätzlich ähnlich zu Goolis Antwort.

Sehen Sie den Code hier

7
Patrick

In bestimmten Fällen, wenn Sie dieselbe Aufgabe regelmäßig ausführen müssen, ist es möglicherweise eine gute Idee, vergangene Abschlusszeiten als Mittelwert zu verwenden.

Ich habe zum Beispiel eine Anwendung, die die iTunes-Mediathek über ihre COM-Schnittstelle lädt. Die Größe einer bestimmten iTunes-Mediathek nimmt von Start zu Start in Bezug auf die Anzahl der Elemente im Allgemeinen nicht dramatisch zu. In diesem Beispiel ist es daher möglicherweise möglich, die letzten drei Ladezeiten und Laderaten zu verfolgen und den Durchschnitt daraus zu ziehen Berechnen Sie Ihre aktuelle ETA.

Dies wäre sehr viel genauer als eine sofortige Messung und wahrscheinlich auch gleichmäßiger.

Diese Methode hängt jedoch davon ab, dass die Größe des Tasks den vorherigen relativ ähnlich ist, sodass dies bei einer Dekomprimierungsmethode oder einer anderen Methode, bei der ein bestimmter Bytestrom die zu komprimierenden Daten sind, nicht funktioniert.

Nur meine 0,02 $

3
Eric Smith

Zunächst einmal hilft es, einen laufenden gleitenden Durchschnitt zu generieren. Dadurch werden neuere Ereignisse stärker gewichtet.

Bewahren Sie dazu eine Reihe von Samples auf (zirkulärer Puffer oder Liste), jeweils ein Paar von Fortschritt und Zeit. Behalten Sie die letzten N Sekunden der Proben bei. Dann generieren Sie einen gewichteten Durchschnitt der Stichproben:

totalProgress += (curSample.progress - prevSample.progress) * scaleFactor
totalTime += (curSample.time - prevSample.time) * scaleFactor

dabei geht scaleFactor linear von 0 ... 1 als inverse Funktion der Zeit in der Vergangenheit (wodurch neuere Proben stärker gewichtet werden). Natürlich können Sie mit dieser Gewichtung herumspielen.

Am Ende können Sie die durchschnittliche Änderungsrate abrufen:

 averageProgressRate = (totalProgress / totalTime);

Sie können dies verwenden, um die ETA zu ermitteln, indem Sie den verbleibenden Fortschritt durch diese Zahl dividieren.

Dies gibt Ihnen zwar eine gute Trendzahl, aber Sie haben ein weiteres Problem - Jitter. Wenn sich Ihre Fortschrittsrate aufgrund natürlicher Schwankungen ein wenig bewegt (es ist laut) - z. Vielleicht verwenden Sie dies, um die Anzahl der Dateidownloads zu schätzen - Sie werden feststellen, dass das Rauschen leicht dazu führen kann, dass Ihre ETA herumspringt, insbesondere wenn es ziemlich weit in der Zukunft liegt (mehrere Minuten oder länger).

Um zu vermeiden, dass sich Jitter zu stark auf Ihre ETA auswirkt, soll diese durchschnittliche Änderungsrate langsam auf Aktualisierungen reagieren. Eine Möglichkeit, dies zu erreichen, besteht darin, einen zwischengespeicherten Wert von averageProgressRate beizubehalten und ihn nicht sofort auf die gerade berechnete Trendzahl zu aktualisieren, sondern ihn als schweres physisches Objekt mit Masse zu simulieren und dabei eine simulierte "Kraft" auf langsam anzuwenden Bewegen Sie es in Richtung der Trendzahl. Mit der Masse hat es eine gewisse Trägheit und es ist weniger wahrscheinlich, dass es durch Jitter beeinträchtigt wird.

Hier ist eine grobe Probe:

// desiredAverageProgressRate is computed from the weighted average above
// m_averageProgressRate is a member variable also in progress units/sec
// lastTimeElapsed = the time delta in seconds (since last simulation) 
// m_averageSpeed is a member variable in units/sec, used to hold the 
// the velocity of m_averageProgressRate


const float frictionCoeff = 0.75f;
const float mass = 4.0f;
const float maxSpeedCoeff = 0.25f;

// lose 25% of our speed per sec, simulating friction
m_averageSeekSpeed *= pow(frictionCoeff, lastTimeElapsed); 

float delta = desiredAvgProgressRate - m_averageProgressRate;

// update the velocity
float oldSpeed = m_averageSeekSpeed;
float accel = delta / mass;    
m_averageSeekSpeed += accel * lastTimeElapsed;  // v += at

// clamp the top speed to 25% of our current value
float sign = (m_averageSeekSpeed > 0.0f ? 1.0f : -1.0f);
float maxVal = m_averageProgressRate * maxSpeedCoeff;
if (fabs(m_averageSeekSpeed) > maxVal)
{
 m_averageSeekSpeed = sign * maxVal;
}

// make sure they have the same sign
if ((m_averageSeekSpeed > 0.0f) == (delta > 0.0f))
{
 float adjust = (oldSpeed + m_averageSeekSpeed) * 0.5f * lastTimeElapsed;

 // don't overshoot.
 if (fabs(adjust) > fabs(delta))
 {
    adjust = delta;
            // apply damping
    m_averageSeekSpeed *= 0.25f;
 }

 m_averageProgressRate += adjust;
}    
3
Scott S

Ihre Frage ist gut. Wenn sich das Problem in diskrete Einheiten aufteilen lässt, funktioniert eine genaue Berechnung häufig am besten. Leider ist dies möglicherweise nicht der Fall, selbst wenn Sie 50 Komponenten installieren, die jeweils 2% ausmachen, aber eine davon kann sehr umfangreich sein. Eine Sache, mit der ich mäßigen Erfolg hatte, ist die Taktung von CPU und Festplatte und eine anständige Schätzung auf der Grundlage von Beobachtungsdaten. Wenn Sie wissen, dass bestimmte Prüfpunkte wirklich Punkt x sind, können Sie Umgebungsfaktoren (Netzwerk, Festplattenaktivität, CPU-Auslastung) korrigieren. Diese Lösung ist jedoch aufgrund ihrer Abhängigkeit von Beobachtungsdaten nicht allgemeiner Natur. Durch die Verwendung von Zusatzdaten wie der Dateigröße der U/min-Datei konnte ich meine Fortschrittsbalken präziser gestalten, aber sie sind niemals kugelsicher.

2
ojblass

Einheitliche Mittelung

Der einfachste Ansatz wäre, die verbleibende Zeit linear vorherzusagen:

t_rem := t_spent ( n - prog ) / prog

wobei t_rem die vorhergesagte ETA ist, t_spent die seit Beginn der Operation verstrichene Zeit ist, prog die Anzahl der aus ihrer vollen Menge abgeschlossenen Mikrotasks n. Zur Erklärung --n kann die Anzahl der zu verarbeitenden Zeilen in einer Tabelle oder die Anzahl der zu kopierenden Dateien sein.

Bei dieser Methode ohne Parameter muss man sich nicht um die Feinabstimmung des Abschwächungsexponenten kümmern. Der Kompromiss besteht in einer schlechten Anpassung an eine sich ändernde Fortschrittsrate, da alle Stichproben den gleichen Beitrag zur Schätzung leisten, wohingegen es nur möglich ist, dass neuere Stichproben mehr Gewicht haben als alte, was uns dazu führt

Exponentielle Glättung der Rate

bei der die Standardtechnik darin besteht, die Fortschrittsrate durch Mitteln vorheriger Punktmessungen zu schätzen:

rate := 1 / (n * dt); { rate equals normalized progress per unit time }
if prog = 1 then      { if first microtask just completed }
    rate_est := rate; { initialize the estimate }
else
begin
    weight   := Exp( - dt / DECAY_T );
    rate_est := rate_est * weight + rate * (1.0 - weight);
    t_rem    := (1.0 - prog / n) / rate_est;
end;

dabei gibt dt die Dauer der letzten abgeschlossenen Mikrotask an und entspricht der Zeit, die seit der letzten Fortschrittsaktualisierung vergangen ist. Beachten Sie, dass weight keine Konstante ist und entsprechend der Zeitspanne angepasst werden muss, in der eine bestimmte rate beobachtet wurde, da der exponentielle Abfall der vorherigen Messungen umso höher ist, je länger wir eine bestimmte Geschwindigkeit beobachten. Die Konstante DECAY_T gibt die Zeitspanne an, in der das Gewicht einer Probe um den Faktor e abnimmt. SPWorley selbst schlug eine ähnliche Modifikation des Vorschlags von gooli vor, obwohl er sie auf den falschen Begriff anwendete. Ein exponentieller Durchschnitt für äquidistante Messungen ist:

Avg_e(n) = Avg_e(n-1) * alpha + m_n * (1 - alpha)

aber was ist, wenn die Samples nicht äquidistant sind, wie es bei Zeiten in einer typischen Fortschrittsanzeige der Fall ist? Berücksichtigen Sie, dass die alpha oben nur ein empirischer Quotient ist, dessen wahrer Wert ist:

alpha = Exp( - lambda * dt ),

dabei ist lambda der Parameter des Exponentialfensters und dt der Änderungsbetrag seit der vorherigen Stichprobe, der keine Zeit, sondern ein linearer und additiver Parameter sein muss. alpha ist für äquidistante Messungen konstant, variiert jedoch mit dt.

Markieren Sie, dass diese Methode auf einer vordefinierten Zeitkonstante beruht und zeitlich nicht skalierbar ist. Mit anderen Worten, wenn genau derselbe Prozess durch einen konstanten Faktor gleichmäßig verlangsamt wird, wird dieses frequenzbasierte Filter proportional empfindlicher gegenüber Signalschwankungen, da weight bei jedem Schritt verringert wird. Wenn wir jedoch eine Glättung unabhängig von der Zeitskala wünschen, sollten wir überlegen

Exponentielle Glättung der Langsamkeit

dies ist im Wesentlichen die Glättung der Rate auf den Kopf gestellt mit der zusätzlichen Vereinfachung einer Konstanten weight von, weil prog in äquidistanten Schritten wächst:

slowness := n * dt;   { slowness is the amount of time per unity progress }
if prog = 1 then      { if first microtask just completed }
    slowness_est := slowness; { initialize the estimate }
else
begin
    weight       := Exp( - 1 / (n * DECAY_P ) );
    slowness_est := slowness_est * weight + slowness * (1.0 - weight);
    t_rem        := (1.0 - prog / n) * slowness_est;
end;

Die dimensionslose Konstante DECAY_P bezeichnet die normalisierte Fortschrittsdifferenz zwischen zwei Stichproben, deren Gewichte im Verhältnis eins zu e stehen. Mit anderen Worten, diese Konstante bestimmt die Breite des Glättungsfensters in der Fortschrittsdomäne und nicht in der Zeitdomäne. Diese Technik ist daher unabhängig von der Zeitskala und hat eine konstante räumliche Auflösung.

Weitere Forschung: Adaptive exponentielle Glättung

Sie können nun die verschiedenen Algorithmen der adaptiven exponentiellen Glättung ausprobieren. Denken Sie nur daran, es auf slowess anstatt auf rate anzuwenden.

1
Ant_222

Ich wünschte immer, diese Dinge würden mir einen Bereich verraten. Wenn es heißt: "Diese Aufgabe wird höchstwahrscheinlich in 8 Minuten bis 30 Minuten erledigt.", Dann habe ich eine Vorstellung davon, welche Art von Pause ich machen soll. Wenn es überall hüpft, bin ich versucht, es zu beobachten, bis es sich beruhigt, was eine große Zeitverschwendung ist.

0
Nosredna

Ich habe versucht, Ihre "einfache"/"falsche"/"OK" -Formel zu vereinfachen, und es funktioniert am besten für mich:

t / p - t

In Python:

>>> done=0.3; duration=10; "time left: %i" % (duration / done - duration)
'time left: 23'

Das spart eine Operation im Vergleich zu (dur * (1-done)/done). Und im von Ihnen beschriebenen Edge-Fall spielt es kaum eine Rolle, den Dialog 30 Minuten lang zu ignorieren, nachdem Sie die ganze Nacht gewartet haben.

Vergleichen dieser einfachen Methode mit der von Transmission verwendeten , ich fand es bis zu 72% genauer.

0
Cees Timmerman