2009-05-12 22 views
14

Estoy buscando la mejor manera de calcular el ETA de una operación (IE: descarga de archivos) usando una información de progreso lineal.¿La mejor manera de calcular la ETA de una operación?

que permite decir que tengo el siguiente método que es llamada:

void ReportProgress(double position, double total) 
{ 
    ... 
} 

Tengo un par de ideas:

  • calcular el progreso en una cantidad fija de tiempo (como últimos 10s) y use esa velocidad como una velocidad promedio para la operación
  • mantenga un conjunto de los últimos x progresos que se ha informado, calcule la velocidad de cada incremento y use el promedio
+13

Independientemente de cómo no hacerlo de la misma forma que la copia de archivos de Microsoft pantalla de progreso –

+1

Bastante similar a esta pregunta: http: // stackoverflow.com/questions/798800/whats-the-best-way-to-calculate-remaining-download-time –

+0

Muchas gracias, no lo encontré antes, ¿qué debo hacer ahora? (La primera vez que pregunto en stackoverflow :)) – Maghis

Respuesta

7

De hecho, me desprecian tanto esas ideas porque han mordido a mí antes como desarrollador.

El primero no tiene en cuenta la situación en la que la operación realmente se vuelve más rápida, dice que hay 10 minutos para ir y vuelvo después de 3 y está terminado.

El segundo no tiene en cuenta que la operación se vuelve más lenta: creo que Windows Explorer debe usar este método ya que siempre parece tomar el 90% del tiempo copiando el 90% de los archivos, luego otro 90% del tiempo copiando el último 10% de los archivos :-).

Hace tiempo que me he tomado el cálculo de esas cifras y promediarlas. A los clientes no les importa (tampoco les importaban las otras dos opciones, solo querían ver algún progreso en) pero me hace sentir mejor, y eso es todo lo que me importa al final del día ;-)

+0

Lo sé, los clientes rara vez lo notan, pero como desarrollador de software estoy casi obsesionado con este tipo de cosas :). Promoverlos es una buena idea. – Maghis

0

Depende de qué tan consistente sea el tiempo de operación. Si es consistente, sería perfectamente razonable usar el tiempo promedio de las operaciones previas. Si no es así, es mejor sincronizar la operación actual y extrapolar.

Edit: Si la operación no es consistente con las ejecuciones anteriores, y también inconsistente de principio a fin, entonces usted tiene un problema indestructible. Predecir lo impredecible siempre es divertido :)

Puede decidir por adelantado si desea subestimar o sobreestimar, y agregar un factor de dulce a la estimación. Por ejemplo, si desea sobreestimar, y el primer 10% tarda 6 segundos, puede extrapolar a 60 segundos y luego multiplicar por 1,5 para obtener una estimación total de 90 segundos. A medida que el porcentaje completado crece, disminuya el factor de dulce de azúcar hasta que al 100% se convierta en 1.0.

+0

Consideremos una descarga de archivos, la velocidad real podría cambiar mucho y dependiendo de las variables que no puedo controlar. La ETA debe parecer razonable para el usuario final. (Tal vez debería aclarar mejor la pregunta) – Maghis

5

Algo como esto debe hacer el truco:

void ReportProgress(double position, double total) 
{ 
    static TimeType startTime; 

    if (position == 0) 
    { 
     startTime = GetTime(); 
     return; // to avoid a divide-by-zero error 
    } 

    TimeType elapsedTime = GetTime() - startTime; 
    TimeType estimatedRemaining = elapsedTime * total/position; 
    TimeType estimatedEndTime = GetTime() + estimatedRemaining; 

    // Print the results here 
} 

La estimación se acerca más a la verdad que el progreso se acerca al 100%

+0

Básico pero bueno, tal vez suponga que el tiempo de operación es muy constante. Mientras progresa, el tiempo estimado siempre es más lento convergiendo al "tiempo restante real". IE: en el caso de la descarga, otra descarga podría finalizar y la velocidad de descarga se duplicará, en este punto el tiempo estimado tomará mucho para ser exacto. – Maghis

+0

Absolutamente cierto, y ese es el problema con las estimaciones. Es igualmente posible que se inicie otra descarga, lo que provocará que la velocidad de descarga se reduzca a la mitad. –

+2

Creo que su cálculo para 'estimatedRemaining' le está dando realmente el _total_tiempo estimado. Probablemente desee 'TimeType estimatedRemaining = (elapsedTime * (total/position)) - elapsedTime'. – tkocmathla

1

Si quiere una ETA en lugar de una 'barra de progreso', ¿puede proporcionar más de una cifra?

Calcule la velocidad promedio de descarga durante un período de tiempo determinado (dependiendo de cuánto tiempo la descarga general pueda durar, si está buscando más de 10 minutos, entonces cada 5s aproximadamente estaría bien) y mantenga un registro de los promedios.

Luego puede proporcionar dos cifras, una estimación superior e inferior.

Si está seguro de que los promedios serán una buena indicación del tiempo total de descarga, podría mostrar el percentil 40 y el 60. Si el tiempo promedio de descarga varía ampliamente, entonces el 10 y el 90 podrían se mejor

Prefiero ver un estadio de béisbol '21 -30 minutos 'y es preciso que se le diga 29 min 35.2 segundos y esté a millas de distancia, y varíe tremendamente de una actualización a la siguiente.

4

Creo que este problema es bastante insoluble, pero es posible crear algunas estimaciones precisas con un poco más de conocimiento del proceso que se está ejecutando. Y en los casos en que hay grandes incógnitas, es mejor informar al usuario de esas incógnitas para que puedan tenerlas en cuenta.

Para tomar el ejemplo sencillo de la descarga de un lote de archivos tiene dos variables conocidas:

  • El número de archivos
  • El tamaño de los archivos

Para cada archivo no existe una sobrecarga constante (el tiempo que lleva establecer una conexión y el tiempo que lleva abrir un archivo en el sistema de archivos). También está el tiempo de descarga obvio asociado con el tamaño de los archivos. Crear una función que pueda expresar esto como el tiempo restante en términos de la velocidad de descarga actual es fácil y preciso, siempre que la velocidad de descarga no fluctúe demasiado. Pero ahí radica el problema.

Con un modelo preciso de la operación que está realizando, es fácil predecir cuánto tiempo llevará, siempre que no haya influencias externas. Y eso es raramente posible.

Sin embargo, podría buscar una solución que intente comprender y explicar estas influencias externas. El usuario puede encontrar útil recibir una alerta cuando la velocidad cambia drásticamente, ya que puede ajustar sus planes para que se ajusten a la nueva ETA. También puede ser útil explicar qué factores están afectando la operación actual. por ejemplo,

Your download will complete in 6 minutes, if the download speed stays at 50k/s 

Esto permite al usuario hacer algunas conjeturas si saben que las velocidades pueden cambiar. Y finalmente conduce a menos frustraciones.

4

Bram Cohen ha hablado un poco de esto. Él ha puesto mucho esfuerzo en los cálculos de ETA en BitTorrent (sin embargo, en una charla mencionó que nadie se ha acercado a él y le ha dicho "¡buenos cálculos de ETA en bittorrent man!"). No es un problema simple.

Algunos enlaces relevantes:

+0

Muchas gracias por los enlaces, no los noté en la primera vez. Ahora estoy de regreso en una tarea similar y tenía curiosidad por echar un vistazo a mi pregunta. – Maghis

1

En Python:

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

¿Puedes explicar lo que hiciste? –

Cuestiones relacionadas