为什么进度条如此不准确?

乍一看,生成准确的时间估计似乎相当容易。毕竟,生成进度条的算法知道它需要在时间…之前完成的所有任务。对吗?

在大多数情况下,源算法确实提前知道它需要做什么。然而,确定执行每个步骤所需的时间即使不是几乎不可能,也是一项非常困难的任务。

并非所有任务都是平等创建的

实现进度条的最简单方法是使用任务计数器的图形表示。其中,完成百分比简单地计算为已完成任务/任务总数。虽然这在第一个想法上是合乎逻辑的,但重要的是要记住,(显然)有些任务需要更长的时间才能完成。

请考虑安装程序执行的以下任务:

创建文件夹结构。 解压缩并复制价值1 GB的文件。 创建注册表项。 创建开始菜单项。

在本例中,步骤1、3和4将很快完成,而步骤2将需要一些时间。因此,进行简单计数的进度条会非常快地跳到25%,在步骤2正在进行时会停滞一段时间,然后几乎立即跳到100%。

这种类型的实现实际上在进度条中相当常见,因为如上所述,它很容易实现。但是,正如您所看到的,由于与剩余时间相关,它会受到不成比例的任务的影响,从而影响实际进度百分比。

要解决此问题,一些进度条可能会使用步骤加权的实现。考虑上面的步骤,其中为每个步骤分配了相对权重:

创建文件夹结构。[重量=1]。 解压缩并复制价值1 GB的文件。[重量=7]。 创建注册表项。[重量=1]。 创建开始菜单项。[重量=1]

使用此方法,进度条将以10%的增量移动(因为总权重为10),其中步骤1、3和4在完成时移动10%,步骤2移动70%。虽然肯定不是完美的,但是像这样的方法是一种简单的方法,可以增加进度条百分比的精确度。

过去的结果不能保证未来的表现

考虑一个简单的例子,我让你数到50,而我用秒表给你计时。假设你在10秒内数到25。可以合理地假设您将在额外的10秒内计算剩余的数字,因此跟踪此情况的进度条将在剩余10秒的时间内显示完成50%。

然而,一旦你数到25,我就开始向你扔网球。这很可能会打破你的节奏,因为你的注意力已经从严格的数数转移到了躲避扔向你的球上。假设你能够继续计数,你的步伐肯定会放慢一点。所以现在进度条仍然在移动,但速度慢得多,估计的时间要么保持不变,要么实际上攀升得更高。

有关这一点的更实际示例,请考虑文件下载。您当前正在以1 MB/s的速率下载一个100 MB的文件。这很容易确定预计完成的时间。但在75%的路程中,会出现一些网络拥塞,您的下载速率会降至500 KB/s。

根据浏览器计算剩余时间的方式,您的ETA可能会立即从25秒变为50秒(仅使用当前状态:剩余大小/下载速度),或者,最有可能的是,浏览器使用滚动平均算法,该算法将针对传输速度的波动进行调整,而不会向用户显示显著的跳跃。

关于下载文件的滚动算法的示例可能如下所示:

记住前60秒的传输速度,用最新的值替换最旧的值(例如,第61个值替换第一个值)。 为了计算的目的,有效转移率是这些测量值的平均值。 剩余时间的计算方式为:剩余大小/有效下载速度

因此,使用上面的场景(为简单起见,我们将使用1 MB=1,000 KB):

下载到75秒时,我们记住的60个值每个都是1,000 KB。有效传输速率为1,000 KB(60,000 KB/60),剩余时间为25秒(25,000 KB/1,000 KB)。 在76秒(传输速度降至500 KB)时,有效下载速度为~992KB(59,500 KB/60),剩余时间约为24.7秒(24,500 KB/992KB)。 77秒:有效速度=~983KB(59,000 KB/60),剩余时间约为24.4秒(24,000 KB/983KB)。 78秒:有效速度=975 KB(58,500 KB/60),剩余时间约为24.1秒(23,500 KB/975 KB)。

您可以看到这里出现的模式,因为下载速度的下降慢慢合并到用于估计剩余时间的平均值中。在这种方法下,如果DIP只持续了10秒,然后返回到1MB/s,用户不太可能注意到差异(除了估计时间倒计时中非常小的停顿)。

切入要害-这只是一种简单的方法,用于将信息传递给最终用户以了解实际的根本原因…

你不能准确地确定一些不确定的东西。

最终,进度条的不准确性归结为它试图确定不确定的事情的时间这一事实。因为计算机同时按需和在后台处理任务,所以几乎不可能知道将来任何时候都有哪些系统资源可用,而完成任何任务都需要系统资源的可用性。

再来看另一个示例,假设您在执行相当密集的数据库更新的服务器上运行程序升级。在此更新过程中,用户然后向此系统上运行的另一个数据库发送要求很高的请求。现在,服务器资源(特别是数据库资源)必须同时处理升级请求和用户发起的查询-这种情况肯定会对执行时间造成不利影响。或者,用户可以发起大文件传输请求,这将对存储吞吐量造成负担,这也会降低性能。或者可以启动执行内存密集型进程的计划任务。你明白我的意思。

对于日常用户来说,考虑运行Windows Update或病毒扫描可能是更现实的情况。这两个操作都在后台执行资源密集型操作。因此,每个进程取决于用户当时正在做什么。如果您在运行此程序时正在阅读电子邮件,则很可能对系统资源的需求较低,并且进度条将持续移动。另一方面,如果您正在进行图形编辑,那么您对系统资源的需求将会大得多,这将导致进度条移动变得精神分裂。

总体而言,这只是一个简单的问题,没有水晶球。即使是系统本身也不知道它在未来的任何时候将承受什么负载。

归根结底,这真的无关紧要。

进度条的目的是,嗯,表明确实正在取得进展,并且各个进程没有挂起。进度指示器准确的时候很好,但是不准确的时候通常只是个小麻烦。在大多数情况下,开发人员不会在进度条算法上投入大量时间和精力,因为坦率地说,还有更重要的任务需要花费时间。

当然,当进度条立即跳到99%完成,然后让您为剩下的1%等待5分钟时,您完全有理由感到恼火。但是,如果各个程序总体运行良好,只需提醒您自己,开发人员有明确的优先顺序。