在窗口中显示下载状态时,我得到如下信息:

1)文件总大小(f)

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

3)当前下载速度

天真的剩余时间计算将为(f-f')/(s),但此值是不稳定的(剩余6m/剩余2h/剩余5m!deja vu ?! :)

是否会有一个既稳定又没有错误的计算方法(即使下载即将完成也显示1h)?

最佳答案

我们通过以下方式解决了类似的问题。我们对下载在整个时间内的速度并不感兴趣,只是对根据最近的事件预计需要花费多长时间而感到不满意,但是,正如您所说的那样,下载的时间并不是那么近,以至于整个数字都在跳跃。

我们对整个时间段不感兴趣的原因是,下载可以以半小时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
    

    您可以更改分辨率(1秒)和历史记录(300)以适合您的情况,但是我们发现5分钟的时间足够长,可以消除异常情况,但仍会及时调整以适应更永久的更改。

    关于algorithm - 在下载窗口中使用稳定的 'download-time-remaining'算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1788283/

    10-11 23:13
    查看更多