为了获得最佳性能,您可能只使用 long 数组而不是列表。
我们曾经有一个类似的要求来实现下载时间估计器,并且我们使用循环缓冲区来存储最后N
几秒的速度。
我们对整个时间的下载速度不感兴趣,只是根据最近的活动大致预计需要多长时间,但不是最近到数据会到处乱跳(例如,如果我们刚刚使用最后一秒计算)。
我们对整个时间范围不感兴趣的原因是下载可能会在半小时内达到 1M/s,然后在接下来的十分钟内切换到 10M/s。尽管您现在的下载速度非常快,但前半小时会严重降低平均速度。
我们创建了一个循环缓冲区,每个单元格保存 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.
这应该很容易适应您自己的要求。总和是“缓存”信息的一个很好的功能,它可以让你的代码更快。我的意思是:如果你需要计算总和或平均值,你只能在数据发生变化时才能计算出来,并使用最少的必要计算。
另一种方法是在请求时将所有十个数字相加,这在将另一个值加载到缓冲区时会比单个减法/加法要慢。