Algo для стабильного "остатка времени загрузки" в окне загрузки

Пока вы показываете статус загрузки в окне, у меня есть информация вроде:

1) Общий размер файла (f)

2) Загруженный размер файла (f ')

3) Текущая скорость загрузки (ов)

Наивное вычисление времени будет (f-f ')/(s), но это значение является способным к колебанию (оставшееся 6 м/оставшееся 2h/5m, оставшееся! deja vu?!:)

Будет ли вычисление, которое является более стабильным и не очень ошибочным (показывая 1 ч, даже когда загрузка будет завершена)?

Ответ 1

Мы решили аналогичную задачу следующим образом. Нам было неинтересно, насколько быстро загрузка была на протяжении всего времени, примерно в том же году, как долго ожидалось, чтобы она основывалась на недавней активности, но, как вы говорите, не так недавно, что цифры будут прыгать повсюду.

Причина, по которой нас не интересовали все временные рамки, заключалась в том, что загрузка может составлять 1 М/с в течение получаса, а затем переключиться на 10 М/с в течение следующих десяти минут. Этот первый полчаса будет сильно тянуть среднюю скорость, несмотря на то, что вы теперь хорошо следите за темпами.

Мы создали круговой буфер, в каждой ячейке которого хранилось количество, загруженное за 1-секундный период. Размер кругового буфера составлял 300, что обеспечивало 5 минут исторических данных, и каждая ячейка была инициализирована до нуля.

Мы также поддерживали общую сумму (сумму всех записей в буфере, а также изначально нуль) и счетчик (нуль, очевидно).

Каждую секунду мы выяснили, сколько данных было загружено с последней секунды, а затем:

  • вычесть текущую ячейку из общей суммы.
  • поместите текущую цифру в эту ячейку и продвиньте указатель ячейки.
  • добавьте текущий показатель в общую сумму.
  • увеличить счетчик, если он еще не 300.
  • обновить фигуру, отображаемую пользователю, на основе total/count.

В принципе, в псевдокоде:

def init (sz):
    buffer = new int[sz]
    for i = 0 to sz - 1:
        buffer[i] = 0 
    total = 0
    count = 0
    index = 0
    maxsz = sz

def update (kbps):
    total = total - buffer[index] + kbps
    buffer[index] = kbps
    index = (index + 1) % maxsz
    if count < maxsz:
        count = count + 1
    return total / count

Вы можете изменить свое разрешение (1 секунду) и историю (300) в соответствии с вашей ситуацией, но мы обнаружили, что 5 минут были более чем достаточно длинными, чтобы сгладить неровности, но все же постепенно скорректировались на более постоянные изменения своевременно.

Ответ 3

Я предпочитаю использовать среднюю скорость за последние 10 секунд и разделять оставшуюся часть с этим. Разделение на текущую скорость до слишком неустойчивой при делении на среднее значение всего хода не может обрабатывать постоянные изменения скорости (например, запускается другая загрузка).

Ответ 4

Почему бы не вычислить скорость загрузки в среднем по всей загрузке, то есть:

s = f' / elapsed time

Таким образом, он со временем будет сглажен.