Algo在下载窗口中提供稳定的"下载剩余时间"

Abh*_*hek 11 algorithm math

在窗口中显示下载状态时,我有以下信息:

1)文件总大小(f)

2)下载文件大小(f')

3)当前下载速度

一个天真的剩余时间计算将是(f-f')/(s),但这个值是不稳定的(剩余6米/剩余2小时/剩余5米!似曾相识?!:)

是否会有更稳定且非极端错误的计算(即使下载即将完成,也会显示1h)?

pax*_*blo 14

我们通过以下方式解决了类似的问题.我们对整个下载速度的持续时间并不感兴趣,只是根据最近的活动大致预计会花多长时间,但正如你所说的那样,并不是最近的数据会在各地跳跃.

我们对整个时间框架不感兴趣的原因是下载速度可以达到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
    buffer[index] = kbps
    index = (index + 1) % maxsz
    if count < maxsz:
        count = count + 1
    return total / count
Run Code Online (Sandbox Code Playgroud)

您可以更改您的分辨率(1秒)和历史记录(300)以适应您的情况,但我们发现5分钟足够长,以至于平滑了违规行为,但仍然会逐渐适应更持久的变化.


Jon*_*ehl 10

平滑s(指数移动平均或类似).