3

ETC =“预计完成时间”

我正在计算循环运行所需的时间,并向用户显示一些数字,告诉他/她整个过程大约需要多少时间。我觉得这是每个人偶尔都会做的常见事情,我想知道您是否有任何遵循的准则。

这是我目前正在使用的一个示例:

int itemsLeft; //This holds the number of items to run through.
double timeLeft;
TimeSpan TsTimeLeft;
list<double> avrage;
double milliseconds; //This holds the time each loop takes to complete, reset every loop.

//The background worker calls this event once for each item. The total number 
//of items are in the hundreds for this particular application and every loop takes
//roughly one second.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //An item has been completed!

    itemsLeft--;
    avrage.Add(milliseconds);

    //Get an avgrage time per item and multiply it with items left.
    timeLeft = avrage.Sum() / avrage.Count * itemsLeft;
    TsTimeLeft = TimeSpan.FromSeconds(timeLeft);

    this.Text = String.Format("ETC: {0}:{1:D2}:{2:D2} ({3:N2}s/file)", 
        TsTimeLeft.Hours, 
        TsTimeLeft.Minutes, 
        TsTimeLeft.Seconds, 
        avrage.Sum() / avrage.Count);

    //Only using the last 20-30 logs in the calculation to prevent an unnecessarily long List<>.
    if (avrage.Count > 30) 
        avrage.RemoveRange(0, 10);

    milliseconds = 0;
}

//this.profiler.Interval = 10;
private void profiler_Tick(object sender, EventArgs e)
{
    milliseconds += 0.01;
}

由于我是一名刚开始职业生涯的程序员,我很想知道你在这种情况下会做什么。我主要关心的是我为每个循环计算和更新 UI,这是不好的做法吗?

当涉及到这样的估计时,有什么做/不做的事情吗?是否有任何首选方法,例如每秒更新一次、每十个日志更新一次、分别计算和更新 UI?此外,ETA/ETC 何时是一个好/坏的主意。

4

2 回答 2

4

估计流程所用时间的真正问题是工作量的量化。一旦你可以量化它,你就可以做出更好的估计

良好估计的例子

  • 文件系统 I/O 或网络传输。文件系统性能好不好,你可以提前知道,可以量化要处理的总字节数,可以衡量速度。一旦你有了这些,一旦你可以监控你传输了多少字节,你就会得到一个很好的估计。随机因素可能会影响您的估计(即同时启动应用程序),但您仍然会得到一个有意义的值

  • 对大型流进行加密。由于上述原因。即使您正在计算 MD5 哈希,您也始终知道已经处理了多少块,要处理多少块以及总数。

  • 物品同步。这有点棘手。如果您可以假设单位工作量是恒定的,或者您可以很好地估计在方差低或不显着时处理项目所需的时间,那么您可以对流程进行另一个很好的估计。选择电子邮件同步:如果您不知道消息的字节大小(否则您属于情况 1)但通常的做法是大多数电子邮件的大小完全相同,那么您可以使用时间的平均值下载/上传所有已处理的电子邮件,以估计处理一封电子邮件所需的时间。这在 100% 的情况下不会起作用,并且出现错误,但您仍然会看到大型帐户上的进度条

一般来说,规则是,如果您有一个您知道数字的同质过程,您可以对 ETC/ETA(ETA 实际上是操作预计完成的日期和时间)做出一个很好的估计。同质性是指处理一个工作项的时间可以与其他项进行比较,即处理前一项所花费的时间用于估计未来。数字用于进行正确的计算。

错误估计的例子

  • 对许多大小未知的文件进行操作。这一次您只知道要处理(例如下载)多少个文件,但您事先不知道它们的大小。一旦文件的大小有很大的差异,您就会看到麻烦。下载了一半的文件,当这些是最小的,总计占总字节数的 10% 时,可以说是一半吗?不!您只是看到进度条快速增长到 50%,然后缓慢增长

  • 异构过程。例如 Windows 安装。正如@HansPassant 所指出的,Windows 安装提供了一个比坏的估计更糟糕的估计。安装 Windows 软件涉及多个过程,包括:文件复制(可以估计)、注册表修改(通常从未估计)、事务代码的执行。真正的问题是最后一个。下面讨论涉及执行自定义安装程序代码的事务处理

  • 执行通用代码。这是永远无法估计的。代码片段涉及条件语句。这些的执行涉及根据代码外部的条件更改路径。这意味着,例如,无论您是否安装了打印机,无论您是否拥有本地或域帐户等,程序的行为都会有所不同。

结论

估计软件过程的持续时间既不是不可能的,也不是精确的/*确定性* 任务。

  • 这并非不可能,因为即使在代码片段的情况下,您也可以为您的代码找到一个模型(选择一个 LU 分解作为示例,这可能是估计的)。或者你可以重新设计你的代码,将它分成一个估计阶段——你首先确定分支条件——和一个执行阶段,在这个阶段中,所有预先确定的分支都被采用。我说可能是因为这个任务实际上是不可能的:大多数代码将分支确定为先前条件的影响,这意味着估计分支实际上涉及运行代码。鸡和蛋圈

  • 这不是一个确定性的过程。计算机系统,尤其是当多任务处理受到许多可能影响您估计过程的随机因素的影响时。在运行您的流程之前,您永远不会得到正确的估计。最多,您可以检测外部因素并重新估计您的过程。当您接近流程结束时fork,您的估计和实际流程持续时间之间的数学收敛为零(lim [x->N] |est(N) - real(N)| == 0,其中 N 是流程期间)

于 2013-05-13T12:19:18.353 回答
2

如果您的用户界面如此晦涩,以至于您必须解释 ETC 并不意味着 Etcetera,那么您做错了。每个用户都了解进度条的作用,不要帮助。

没有什么比不准确的进度条更烦人了。特别是那些承诺快速完成但没有交付的人。我会把 Windows 上任何安装程序显示的进度条作为一个很好的例子,说明它从根本上被破坏了。只是不是您应该追求的实施的光辉示例。

这样的进度条被破坏了,因为完全不可能预先猜出安装程序需要多长时间。文件系统具有非常不可预测的性能。这是估计执行时间的一个非常常见的问题。更好的 UI 模型是您在视频播放器和 Windows 8 中的许多程序中看到的旋转点。或者常见的 ProgressBar 控件支持的选取框样式。只是反馈说“我还没死,正在努力”。即使是沙漏光标也比一个错误的估计要好。如果您要报告的内容超出了用户真正感兴趣的技术性,那么请毫不犹豫地展示它。就像您已处理的文件数或已下载的千字节数。数字的实际值没有那么有用,

于 2013-05-13T10:46:07.020 回答