Ответ 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 минут были более чем достаточно длинными, чтобы сгладить неровности, но все же постепенно скорректировались на более постоянные изменения своевременно.