C# 计算剩余时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/473355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:49:44  来源:igfitidea点击:

Calculate Time Remaining

c#algorithm

提问by Aaron Smith

What's a good algorithm for determining the remaining time for something to complete? I know how many total lines there are, and how many have completed already, how should I estimate the time remaining?

确定某事完成的剩余时间的好算法是什么?我知道总共有多少行,已经完成了多少行,我应该如何估计剩余的时间?

采纳答案by JoshBerke

Why not?

为什么不?

(linesProcessed / TimeTaken)(timetaken / linesProcessed) * LinesLeft = TimeLeft

(linesProcessed / TimeTaken)(timetaken / linesProcessed) * LinesLeft = TimeLeft

TimeLeftwill then be expressed in whatever unit of time timeTakenis.

TimeLeft然后将以任何时间单位表示timeTaken

Edit:

编辑:

Thanks for the comment you're right this should be:

感谢您的评论,这应该是:

(TimeTaken / linesProcessed) * linesLeft = timeLeft

(TimeTaken / linesProcessed) * linesLeft = timeLeft

so we have

所以我们有

(10 / 100) * 200= 20 Seconds now 10 seconds go past
(20 / 100) * 200= 40 Seconds left now 10 more seconds and we process 100 more lines
(30 / 200) * 100= 15 Seconds and now we all see why the copy file dialog jumps from 3 hours to 30 minutes :-)

(10 / 100) * 200= 20 秒现在 10 秒过去
(20 / 100) * 200= 40 秒现在还有 10 秒我们处理了 100 多行
(30 / 200) * 100= 15 秒现在我们都明白了为什么复制文件对话框从 3 小时跳到 30 分钟 :-)

回答by chills42

That really depends on what is being done... lines are not enough unless each individual line takes the same amount of time.

这真的取决于正在做什么......除非每个单独的行花费相同的时间,否则行是不够的。

The best way (if your lines are not similar) would probably be to look at logical sections of the code find out how long each section takes on average, then use those average timings to estimate progress.

最好的方法(如果您的代码行不相似)可能是查看代码的逻辑部分,找出每个部分的平均时间,然后使用这些平均时间来估计进度。

回答by GWLlosa

If you know the percentage completed, and you can simply assume that the time scales linearly, something like

如果您知道完成的百分比,并且您可以简单地假设时间是线性的,例如

timeLeft = timeSoFar * (1/Percentage)

timeLeft = timeSoFar * (1/百分比)

might work.

可能工作。

回答by fmsf

there is no standard algorithm i know of, my sugestion would be:

没有我知道的标准算法,我的建议是:

  • Create a variable to save the %
  • Calculate the complexity of the task you wish to track(or an estimative of it)
  • Put increments to the % from time to time as you would see fit given the complexity.
  • 创建一个变量来保存 %
  • 计算您希望跟踪的任务的复杂性(或对其的估计)
  • 考虑到复杂性,您会不时将增量添加到 % 中。

You probably seen programs where the load bar runs much faster in one point than in another. Well that's pretty much because this is how they do it. (though they probably just put increments at regular intervals in the main wrapper)

您可能看到过负载条在某一点上的运行速度比在另一点上快得多的程序。嗯,这几乎是因为他们就是这样做的。(虽然他们可能只是在主包装器中定期增加增量)

回答by Michael Meadows

It depends greatly on what the "something" is. If you can assume that the amount of time to process each line is similar, you can do a simple calculation:

这在很大程度上取决于“某物”是什么。如果您可以假设处理每一行的时间量相似,则可以进行简单的计算:

TimePerLine = Elapsed / LinesProcessed
TotalTime = TimePerLine * TotalLines
TimeRemaining = TotalTime - LinesRemaining * TimePerLine

回答by casperOne

Generally, you know three things at any point in time while processing:

通常,您在处理过程中的任何时间点都知道三件事:

  1. How many units/chunks/items have been processed up to that point in time (A).
  2. How long it has taken to process those items (B).
  3. The number of remaining items (C).
  1. 到那个时间点 (A) 已经处理了多少个单元/块/项目。
  2. 处理这些项目需要多长时间 (B)。
  3. 剩余项目数 (C)。

Given those items, the estimate(unless the time to process an item is constant) of the remaining time will be

给定这些项目,剩余时间的估计(除非处理项目的时间是恒定的)将是

B * C / A

乙*丙/甲

回答by Anthony Mastrean

Make sure to manage perceived performance.

确保管理感知性能

Although all the progress bars took exactly the same amount of time in the test, two characteristics made users think the process was faster, even if it wasn't:

  1. progress bars that moved smoothly towards completion
  2. progress bars that sped up towards the end

尽管所有进度条在测试中花费的时间完全相同,但有两个特征让用户认为过程更快,即使事实并非如此:

  1. 顺利完成的进度条
  2. 向最后加速的进度条

回答by Alexander V

Where time$("ms")represents the current time in milliseconds since 00:00:00.00, and lofrepresents the total lines to process, and xrepresents the current line:

其中time$("ms")代表从 00:00:00.00 开始的当前时间(以毫秒为单位),lof代表要处理的总行数,x代表当前行:

if Ln>0 then
    Tn=Tn+time$("ms")-Ln   'grand total of all laps
    Rn=Tn*(lof-x)/x^2      'estimated time remaining in seconds
end if
Ln=time$("ms")             'start lap time (current time)

回答by Scott Rippey

I'm surprised no one has answered this question with code!

我很惊讶没有人用代码回答这个问题!

The simple way to calculate time, as answered by @JoshBerke, can be coded as follows:

正如@JoshBerke 所回答的,计算时间的简单方法可以编码如下:

DateTime startTime = DateTime.Now;
for (int index = 0, count = lines.Count; index < count; index++) {
    // Do the processing
    ...

    // Calculate the time remaining:
    TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (count - (index+1)) / (index+1));

    // Display the progress to the user
    ...
}

This simple example works great for simple progress calculation.
However, for a more complicated task, there are many ways this calculation could be improved!

这个简单的例子非常适合简单的进度计算。
但是,对于更复杂的任务,可以通过多种方式改进此计算!

For example, when you're downloading a large file, the download speed could easily fluctuate. To calculate the most accurate "ETA", a good algorithm would be to only consider the past 10 seconds of progress. Check out ETACalculator.csfor an implementation of this algorithm!

例如,当您下载大文件时,下载速度很容易波动。要计算最准确的“ETA”,一个好的算法是只考虑过去 10 秒的进度。查看ETACalculator.cs以了解该算法的实现!

ETACalculator.csis from Progression-- an open source library that I wrote. It defines a very easy-to-use structure for all kinds of "progress calculation". It makes it easy to have nested steps that report different types of progress. If you're concerned about Perceived Performance (as @JoshBerke suggested), it will help you immensely.

ETACalculator.cs来自Progression—— 我编写的一个开源库。它为各种“进度计算”定义了一个非常易于使用的结构。使用嵌套步骤可以轻松报告不同类型的进度。如果您担心感知性能(如@JoshBerke 建议的那样),它将极大地帮助您。

回答by Chad Carisch

Not to revive a dead question but I kept coming back to reference this page.
You could create an extension method on the Stopwatch class to get functionality that would get an estimated remaining time span.

不是要复活一个死问题,但我一直回来参考这个页面。
您可以在 Stopwatch 类上创建一个扩展方法,以获取将获得估计剩余时间跨度的功能。

static class StopWatchUtils
{
    /// <summary>
    /// Gets estimated time on compleation. 
    /// </summary>
    /// <param name="sw"></param>
    /// <param name="counter"></param>
    /// <param name="counterGoal"></param>
    /// <returns></returns>
    public static TimeSpan GetEta(this Stopwatch sw, int counter, int counterGoal)
    {
        /* this is based off of:
         * (TimeTaken / linesProcessed) * linesLeft=timeLeft
         * so we have
         * (10/100) * 200 = 20 Seconds now 10 seconds go past
         * (20/100) * 200 = 40 Seconds left now 10 more seconds and we process 100 more lines
         * (30/200) * 100 = 15 Seconds and now we all see why the copy file dialog jumps from 3 hours to 30 minutes :-)
         * 
         * pulled from http://stackoverflow.com/questions/473355/calculate-time-remaining/473369#473369
         */
        if (counter == 0) return TimeSpan.Zero;
        float elapsedMin = ((float)sw.ElapsedMilliseconds / 1000) / 60;
        float minLeft = (elapsedMin / counter) * (counterGoal - counter); //see comment a
        TimeSpan ret = TimeSpan.FromMinutes(minLeft);
        return ret;
    }
}

Example:

例子:

int y = 500;
Stopwatch sw = new Stopwatch();
sw.Start();
for(int x = 0 ; x < y ; x++ )
{
    //do something
    Console.WriteLine("{0} time remaining",sw.GetEta(x,y).ToString());
}

Hopefully it will be of some use to somebody.

希望它对某人有用。


EDIT: It should be noted this is most accurate when each loop takes the same amount of time.
Edit 2: Instead of subclassing I created an extension method.


编辑:应该注意,当每个循环花费相同的时间时,这是最准确的。
编辑 2:我没有创建子类,而是创建了一个扩展方法。