近日做一个软件,需要计算剩余时间。
算法原理就是: 已经耗时*剩余大小/已经处理的大小。
但发现了计算的速度一直抖动, 发现是因为UI在没有进度回调时,也在刷新剩余时间,这样导致了误差。
比如处理1G大小的数据 已经处理了100M 耗时100S, 那么剩余时间就是900S。
如果耗时100.3S时又计算速度,而此时还是只处理了100M(底层没有回调), 那么剩余时间就是902.7S。
假如在100.5时回调了进度100.5M,那么剩余时间就又是900S,这样就有了抖动。
所以正确方法是,只有在底层回调进度时进行计算剩余时间,抖动就少了很多。
现在计算一下正常速度变化, 会不会造成抖动。 假设平均速度时1M/1S
但突然在5秒内速度变成了0.5M/S. 总大小1000M。
100S 100M 剩余时间900S
100.5S 100.25M 剩余时间901.99S 正常情况是899秒
101S 100.5M 剩余时间903.975 正常情况是898秒
....
....
....
但这些是正常结果,就是因为速度变慢了,但可以很大程度解决上面提到的抖动BUG。
假如回调的速度时一次0.95 一次1.05 看看抖动如何,以秒为单位:
总大小1000M。
100S 100M 剩余时间900S
101S 100.95M 剩余时间899.49 大约期望的值
102S 102M 剩余时间898 和正常一样
103S 102.95M 剩余时间897.48 大约期望的值
在这样的误差情况下,剩余时间基本还是递减的,不会抖动。
现在计算一下抖动的临界状态:
t1 = 已经耗时*剩余大小/已经处理的大小。
t2= ( 已经耗时+dt) * (剩余大小-dm) / (已经处理的大小+dm)。
dt 是时间间隔, dm是当前处理的大小。 要抖动 就得t2<=t1
也就是速度突然满到一定程度(比如0),那么t2就会比t1还大。 以一个比值,这里就不计算了。
但如果把前面当成整体,承认这个公式的正确性,那么结果也是值得信赖的, 因为速度的不可预知, 剩余时间肯定也是变化的。