Por que as barras de progresso são tão imprecisas?

À primeira vista, parece que gerar uma estimativa precisa do tempo deve ser bastante fácil. Afinal, o algoritmo que produz a barra de progresso conhece todas as tarefas que precisa fazer com antecedência … certo?

Na maior parte, é verdade que o algoritmo de origem sabe o que precisa fazer com antecedência. No entanto, determinar o tempo que levará para executar cada etapa é uma tarefa muito difícil, se não virtualmente impossível.

Todas as tarefas não são criadas iguais

A maneira mais simples de implementar uma barra de progresso é usar uma representação gráfica do contador de tarefas. Onde a porcentagem concluída é simplesmente calculada como Tarefas Concluídas / Número Total de Tarefas . Embora isso faça sentido lógico à primeira vista, é importante lembrar que (obviamente) algumas tarefas demoram mais para serem concluídas.

Considere as seguintes tarefas realizadas por um instalador:

  1. Crie uma estrutura de pastas.
  2. Descompacte e copie 1 GB de arquivos.
  3. Crie entradas de registro.
  4. Crie entradas do menu inicial.

Neste exemplo, as etapas 1, 3 e 4 seriam concluídas muito rapidamente, enquanto a etapa 2 levaria algum tempo. Portanto, uma barra de progresso trabalhando em uma contagem simples saltaria para 25% muito rapidamente, pararia um pouco enquanto a etapa 2 estava funcionando e, em seguida, saltaria para 100% quase imediatamente.

Na verdade, esse tipo de implementação é bastante comum entre as barras de progresso porque, conforme declarado acima, é fácil de implementar. No entanto, como você pode ver, ele está sujeito a tarefas desproporcionais que distorcem a porcentagem de progresso real, pois se relaciona ao tempo restante.

Para contornar isso, algumas barras de progresso podem usar implementações onde as etapas são ponderadas. Considere as etapas acima, onde um peso relativo é atribuído a cada etapa:

  1. Crie uma estrutura de pastas. [Peso = 1]
  2. Descompacte e copie 1 GB de arquivos. [Peso = 7]
  3. Crie entradas de registro. [Peso = 1]
  4. Crie entradas do menu inicial. [Peso = 1]
Recomendado:  Como definir um limite de tempo de aplicativo no iPhone e iPad

Usando este método, a barra de progresso se moveria em incrementos de 10% (já que o peso total é 10) com as etapas 1, 3 e 4 movendo a barra 10% na conclusão e a etapa 2 movendo-a 70%. Embora certamente não sejam perfeitos, métodos como este são uma maneira simples de adicionar um pouco mais de precisão à porcentagem da barra de progresso.

Resultados anteriores não garantem desempenho futuro

Estimativa

Considere um exemplo simples em que eu lhe peço para contar até 50 enquanto uso um cronômetro para cronometrá-lo. Digamos que você conte até 25 em 10 segundos. Seria razoável supor que você contaria os números restantes em 10 segundos adicionais, portanto, uma barra de progresso rastreando isso mostraria 50% completo com 10 segundos restantes.

Quando sua contagem chega a 25, entretanto, começo a jogar bolas de tênis em você. Provavelmente, isso quebrará seu ritmo, pois sua concentração mudou da contagem estrita de números para as bolas arremessadas em sua direção. Supondo que você seja capaz de continuar contando, seu ritmo certamente diminuiu um pouco. Portanto, agora a barra de progresso ainda está se movendo, mas em um ritmo muito mais lento com o tempo estimado restante parado ou subindo mais alto.

Para um exemplo mais prático disso, considere o download de um arquivo. No momento, você está baixando um arquivo de 100 MB a uma taxa de 1 MB / s. É muito fácil determinar o tempo estimado de conclusão. Mas, em 75% do caminho, ocorre algum congestionamento na rede e sua taxa de download cai para 500 KB / s.

Dependendo de como o navegador calcula o tempo restante, seu ETA pode ir instantaneamente de 25 segundos a 50 segundos (usando apenas o estado atual: Tamanho restante / Velocidade de download ) ou, provavelmente, o navegador usa um algoritmo de média contínua que se ajustaria às flutuações na velocidade de transferência sem exibir saltos dramáticos para o usuário.

Um exemplo de algoritmo contínuo em relação ao download de um arquivo pode funcionar da seguinte forma:

  • A velocidade de transferência dos 60 segundos anteriores é lembrada com o valor mais recente substituindo o mais antigo (por exemplo, o 61º valor substitui o primeiro).
  • A taxa de transferência efetiva para efeito de cálculo é a média dessas medições.
  • O tempo restante é calculado como: Tamanho restante / Velocidade efetiva de download

Portanto, usando nosso cenário acima (por uma questão de simplicidade, usaremos 1 MB = 1.000 KB):

  • Aos 75 segundos de download, nossos 60 valores lembrados seriam cada um de 1.000 KB. A taxa de transferência efetiva é de 1.000 KB (60.000 KB / 60), o que resulta em um tempo restante de 25 segundos (25.000 KB / 1.000 KB).
  • Em 76 segundos (onde a velocidade de transferência cai para 500 KB), a velocidade efetiva de download torna-se ~ 992 KB (59.500 KB / 60), o que resulta em um tempo restante de ~ 24,7 segundos (24.500 KB / 992 KB).
  • Em 77 segundos: Velocidade efetiva = ~ 983 KB (59.000 KB / 60), resultando em tempo restante de ~ 24,4 segundos (24.000 KB / 983 KB).
  • A 78 segundos: Velocidade efetiva = 975 KB (58.500 KB / 60), resultando em tempo restante de ~ 24,1 segundos (23.500 KB / 975 KB).
Recomendado:  Como compartilhar seu Apple Maps Live ETA no iPhone

Você pode ver o padrão emergindo aqui conforme a queda na velocidade de download é lentamente incorporada à média que é usada para estimar o tempo restante. De acordo com este método, se a queda durou apenas 10 segundos e depois voltou a 1 MB / s, o usuário provavelmente não notará a diferença (exceto por uma pequena paralisação na contagem regressiva de tempo estimada).

Chegando ao ponto principal – esta é simplesmente uma metodologia para transmitir informações ao usuário final para a causa subjacente real …

Você não pode determinar com precisão algo que não é determinístico

Em última análise, a imprecisão da barra de progresso se resume ao fato de que ela está tentando determinar um tempo para algo que não é determinístico . Como os computadores processam tarefas sob demanda e em segundo plano, é quase impossível saber quais recursos do sistema estarão disponíveis em qualquer momento no futuro – e é a disponibilidade dos recursos do sistema que é necessária para qualquer tarefa ser concluída.

Usando outro exemplo, suponha que você esteja executando uma atualização de programa em um servidor que executa uma atualização de banco de dados bastante intensa. Durante este processo de atualização, um usuário envia uma solicitação exigente para outro banco de dados em execução neste sistema. Agora os recursos do servidor, especificamente para o banco de dados, estão tendo que processar solicitações tanto para sua atualização quanto para a consulta iniciada pelo usuário – um cenário que certamente será mutuamente prejudicial ao tempo de execução. Como alternativa, um usuário poderia iniciar uma grande solicitação de transferência de arquivo, que sobrecarregaria a taxa de transferência de armazenamento, o que também prejudicaria o desempenho. Ou pode ser iniciada uma tarefa agendada que execute um processo que consome muita memória. Você entendeu a ideia.

Recomendado:  Como solucionar problemas do Android Auto

Como, talvez, uma instância mais realista para um usuário comum – considere executar o Windows Update ou uma verificação de vírus. Ambas as operações executam operações intensivas de recursos em segundo plano. Como resultado, o progresso de cada um depende do que o usuário está fazendo no momento. Se você estiver lendo seu e-mail durante a execução, provavelmente a demanda de recursos do sistema será baixa e a barra de progresso se moverá de forma consistente. Por outro lado, se você estiver editando gráficos, sua demanda de recursos do sistema será muito maior, o que tornará o movimento da barra de progresso esquizofrênico.

No geral, simplesmente não há bola de cristal. Nem mesmo o próprio sistema sabe a que carga estará em qualquer momento no futuro.

Em última análise, isso realmente não importa

A intenção da barra de progresso é, bem, indicar que o progresso está realmente sendo feito e o respectivo processo não está travado. É bom quando o indicador de progresso é preciso, mas normalmente é apenas um pequeno incômodo quando não é. Na maioria das vezes, os desenvolvedores não vão dedicar muito tempo e esforço aos algoritmos da barra de progresso porque, francamente, há tarefas muito mais importantes nas quais gastar tempo.

Claro, você tem todo o direito de ficar chateado quando uma barra de progresso pula para 99% de sua conclusão instantaneamente e o faz esperar 5 minutos pelo 1% restante. Mas se o respectivo programa funcionar bem no geral, lembre-se de que o desenvolvedor tinha suas prioridades bem definidas.