我有一个应用程序,在执行后台任务时,会显示一个进度条,其中包含“估计剩余时间”计算(例如“剩余5秒”)和“估计完成时间”(例如“12点完成”: 59:59“),或者我称之为ETA。
计算此ETA的算法基本上采用随时间推移的“滚动平均值”:
1.每个进度事件都会以当前时间添加到队列中
2.经过一段时间(例如10秒)后,项目将从队列中删除
3. ETA是从队列中的第一个和最后一个项目推断出来的
如果您关心,可以使用源代码:ETACalculator.cs
但是,存在抖动问题。随着每个进度事件被添加到计算中,ETA将稍微更新。假设ETA仅改变0.1s
。这种小抖动很容易导致ETA“颤动”。例如,我没有看到5s,4s,3s等的平滑进展,而是看到了5-5-5-4-5-4-5-4-4-4-4-4。
我在考虑将更新减少到每秒1次,但进度条不太顺畅,而且我真的希望“实际”减速能够实时显示。
我遇到了一个简单的算法,可以减少这种跳跃的抖动。如何消除抖动?
答案 0 :(得分:11)
将实际紧张进度和显示进度分成两个独立的变量。
像现在一样更新紧张的进展。
以固定(相对较快)的间隔,将显示的进度更新为接近实际进度。
一种简单的方法算法是平均两个值
display_progress = (display_progress + actual_progress) / 2
这会抑制价值以反映过去的价值,而不仅仅是直接价值。
您还可以使用以下方法优化平滑度:
display_progress = (P) * display_progress + (1.0-P) * actual_progress
其中P
是0.0
和1.0
之间的常数值。
修改强>
这是可以使用的众多过滤器之一。这个很好,因为它不需要太多记账。
然而,获得完美输出并不是一种选择,因为该缺陷存在于输入中。 “抖动”和“实际减速”之间的差异仅在发生之后才能观察到。
答案 1 :(得分:3)
在没有查看代码的情况下对您的算法不太清楚,但是当您更新ETA时,首先检查当前的ETA,并且只有在新值低于旧值时才更新它。
答案 2 :(得分:0)
这听起来像是要“去抖动”:选择最近X个值中的最小值。