language agnostic - ¿Calcula los tiempos estimados de copias/movimientos de archivos?
language-agnostic file (7)
Creo que los diálogos deberían admitir sus limitaciones. No es molesto porque no ofrece un estimado de tiempo útil, es molesto porque ofrece un estimado que es una tontería obvia.
Por lo tanto, calcule como quiera, basándose en la tasa actual o en la tasa promedio hasta el momento, los promedios móviles descartando valores atípicos, o lo que sea. Depende del funcionamiento y las duraciones típicas de los eventos que lo retrasen, por lo que es posible que tenga diferentes algoritmos cuando sepa que la copia del archivo implica una unidad de red. Pero hasta que su estimación haya sido bastante constante durante un período de tiempo igual al menor de 30 segundos o al 10% del tiempo estimado, muestre "oh querido, parece haber algún tipo de atraco" cuando se frena masivamente, o simplemente ignora si se acelera enormemente.
Por ejemplo, mensajes de diálogo tomados a intervalos de 1 segundo cuando una conexión se detiene brevemente:
remaining: 60 seconds // estimate is 60 seconds
remaining: 59 seconds // estimate is 59 seconds
remaining: delayed [was 59 seconds] // estimate is 12 hours
remaining: delayed [was 59 seconds] // estimate is infinity
remaining: delayed [was 59 seconds] // got data: estimate is 59 seconds
// six seconds later
remaining: 53 seconds // estimate is 53 seconds
Inspirado por esta caricatura de xckd, me pregunté exactamente cuál es el mejor mecanismo para proporcionar una estimación al usuario de una copia / movimiento de archivo.
La etiqueta alt en xkcd dice lo siguiente:
Podrían decir "probablemente la conexión se haya perdido", pero es más divertido hacer un promedio de tiempo ingenuo para darte la esperanza de que si esperas alrededor de 1.163 horas, finalmente terminará.
Ignorando lo gracioso, ¿así es como se hace en Windows? ¿Qué tal otro sistema operativo? ¿Hay una mejor manera?
Hablando de la copia de archivos de red, lo mejor es calcular el tamaño de archivo que se va a transferir, la respuesta de red, etc. Un enfoque que utilicé una vez fue:
Velocidad de conexión = Ping y calcular el tiempo de ida y vuelta para paquetes con 15 Kbytes.
Obtenga mi tamaño de archivo y vea, teóricamente, el tiempo que tomaría si lo rompiera en paquetes de 15 kb usando mi velocidad de conexión.
Vuelva a calcular la velocidad de conexión después de iniciar la transferencia y ajuste el tiempo que se gastará.
Sobre todo, nunca mostraría segundos (solo horas y minutos). Creo que es realmente frustrante cuando te sientas allí y esperas un minuto mientras el temporizador salta entre 10 y 20 segundos. Y siempre muestre información real como: xxx / aaaa MB copiado.
También incluiría algo como esto:
if timeLeft > 5h --> Inform user that this might not work properly if timeLeft > 10h --> Inform user that there might be better ways to move the file if timeLeft > 24h --> Abort and check for problems
También me gustaría informar al usuario si el tiempo estimado varía demasiado
Y si no es demasiado complicado, debe haber una función de verificación automática que verifique si el proceso todavía está activo y funcionando correctamente cada 1-10 minutos (dependiendo de la aplicación).
- Inicie un temporizador global que se active, por ejemplo, cada 1000 milisegundos y actualice un contador de tiempo total elpasado. Llamemos a esta variable "tiempo
elapsedTime
" - Mientras se copia el archivo, actualice alguna variable local con la cantidad ya copiada. Llamemos a esta variable "
totalCopied
" - En el evento de temporizador que se
totalCopied
periódicamente, dividatotalCopied
portotalElapsed
para obtener el número de bytes copiados por intervalo de temporizador (en este caso, 1000 ms). Llamemos a esta variable "bytesPerSec
" - Divida el tamaño total del archivo por
bytesPerSec
y obtenga el número total de segundos teóricamente necesarios para copiar este archivo. Vamos a llamar a esta variableremainingTime
- Reste
elapsedTime
fromremainingTime
yelapsedTime
un cálculo algo preciso para el tiempo de copia de archivo.
He hecho algo similar para estimar cuándo una cola estará vacía, dado que los artículos se están quitando de la cola más rápido de lo que están en cola. Usé regresión lineal sobre las lecturas de N más recientes de (tiempo, tamaño de cola).
Esto da mejores resultados que una ingenua
(bytes_copied_so_far / elapsed_time) * bytes_left_to_copy
He estado reflexionando sobre esto yo mismo. Tengo una rutina de copia, a través de una interfaz de estilo de Windows Explorer, que permite la transferencia de archivos seleccionados desde un dispositivo Android a una PC.
Al comienzo, sé el tamaño total de los archivos que se copiarán, y como estoy usando C # .NET, estoy usando un cronómetro para obtener el tiempo transcurrido y mientras la copia está en progreso, Mantengo un total de lo que se copia hasta ahora, en términos de bytes.
Todavía no lo he probado, pero la mejor manera parece ser esta:
estimado = transcurrido * ((totalSize - copiedSoFar) / copiedSoFar)
Eche un vistazo a mi respuesta a una pregunta similar (y las otras respuestas allí) sobre cómo se calcula el tiempo restante en Windows Explorer.
En mi opinión, solo hay una forma de obtener buenas estimaciones:
- Calcule el número exacto de bytes que se copiarán antes de comenzar el proceso de copiado
- Recalcule su estimación regularmente (cada 1, 5 o 10 segundos, YMMV) según la velocidad de transferencia actual
- La velocidad de transferencia actual puede fluctuar mucho cuando está copiando en una red, por lo tanto, utilice un promedio, por ejemplo, basado en la cantidad de bytes transferidos desde su última estimación.
Tenga en cuenta que el primer punto puede requerir bastante trabajo, si está copiando muchos archivos. Esa es probablemente la razón por la cual los chicos de Microsoft decidieron prescindir de ella. Debe decidir si la sobrecarga adicional creada por ese cálculo vale la pena darle a su usuario una mejor estimación.