Meu programa faz um longo processo para percorrer pelos bytes de Arquivos, e eu gostaria de mostrar para o usuário uma estimativa (atualizada a cada segundo ou algo assim) de quanto tempo +/- ainda vai levar pro processamento acabar.
Ou seja, seria mostrar para o usuário uma contagem regressiva que acaba quando o processamento da tarefa acabar.
É comum ver essas estimativas em Downloads:
Eu já tentei dois tipos de algoritmos diferentes que bolei aqui, mas eles são muito imprecisos e fazem saltos estranhos (como ir de 3s para 523s, e de volta para 2s, por exemplo).
Alguem conhece um bom algoritmo para fazer isso?
Eu acho que as Entradas do Algoritmo seriam algo como:
public long estimarTempoRestante(long workDone, long totalWork, long now) { ??? }
E seria usado +/- assim:
for (int i = 0; i <= 1000000; i++) {
long millisRestantes estimador.estimarTempoRestante(i, long 1000000, System.currentTimeMillis());
System.out.println("Falta cerca de "+(millisRestantes/1000)+"s para terminar.");
}
int total = ???;
int processado = 0;
// total de dados processados no periodo;
processo = 0;
tempoInicio = currentMilis();
while(não fim) {
processo += processaTarefa();
// atualiza o tempo fim
tempoFim = currentMilis();
// se ultrapassar 1 segundo, tente números maiores para melhor precisão
if (tempoFim - tempoInicio >= 1000) {
// atualiza total processado
processado += processo;
// verifica se terminou
if (total == processado) fim;
// efetua calculo para exibição
double periodo = (tempoFim - tempoInicio) / processo; // tempo / qtdProcessadoNoTempo
atualizaCronomero(periodo * (total - processado)); // período * qtdQFalta
// reseta
processo = 0;
tempoInicio = tempoFim;
}
}
Acredito que seja por causa do seu computador ser multi-core ou esteja executando em mais de uma thread, as vezes algumas tarefas são executadas mais rapidamente que outras mesmo que sejam todas iguais.
Acho que o ideal seria contar os bytes processados em um determinado intervalo de tempo e não o tempo que demorou para ser processado um conjunto de bytes.