Для оптимальной производительности вы, вероятно, можете просто использовать массив long, а не список.
В какой-то момент у нас было аналогичное требование для реализации оценщика времени загрузки, и мы использовали кольцевой буфер для храненияскорость в течение каждой из последних N
секунд.
Нас не интересовало, как быстро выполнялась загрузка в течение всего времени, лишь приблизительно, сколько времени она ожидала, основываясь на недавней активности, но не так недавно, что цифры будут прыгать повсюду (например, если бы мы просто использовали последнюю секунду, чтобы вычислить его).
Причина, по которой нас не интересовали все временные рамкиБыло то, что загрузка могла составлять 1 М / с в течение получаса, а затем переключаться на 10 М / с в течение следующих десяти минут.Эти первые полчаса довольно сильно замедляют среднюю скорость, несмотря на то, что вы сейчас загружаете довольно быстро.
Мы создали кольцевой буфер, в каждой ячейке которого содержится количество загруженного за 1-секундный период.Размер циклического буфера составлял 300, что позволяло хранить 5 минут исторических данных, и каждая ячейка была инициализирована нулем.В вашем случае вам потребовалось бы всего десять ячеек.
Мы также поддерживали итоговую сумму (сумму всех записей в буфере, поэтому также изначально равную нулю) и счетчик (изначально равный нулю, очевидно).
Каждую секунду мы выясняем, сколько данных было загружено с последней секунды, а затем:
- вычитаем текущую ячейку из общей суммы.
- помещаем текущую цифрув эту ячейку и продвиньте указатель ячейки.
- добавьте эту текущую цифру к итогу.
- увеличьте счет, если его еще не было 300.
- обновите отображаемую фигурупользователю, исходя из общего количества / количества.
В основном в псевдокоде:
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 # Adjust sum based on deleted/inserted values.
buffer[index] = kbps # Insert new value.
index = (index + 1) % maxsz # Update pointer.
if count < maxsz: # Update count.
count = count + 1
return total / count # Return average.
Это должно быть легко адаптировано к вашим собственным требованиям.Эта сумма - хорошая функция для «кеширования» информации, которая может сделать ваш код еще быстрее.Под этим я подразумеваю: если вам нужно вычислить сумму или среднее значение, вы можете вычислить это только при изменении данных, используя минимальные необходимые вычисления.
Альтернативой может быть функция, которая суммирует вседесять чисел по запросу, что будет медленнее, чем одно вычитание / сложение при загрузке другого значения в буфер.