c# - 计算循环中剩余的估计时间(当迭代次数非常大并且每次迭代所需的时间非常低时)
问题描述
我正在尝试计算 for 循环的总剩余时间。总迭代次数可以超过~1010000000。完成“在这里完成的真正工作”所需的总时间远低于一秒,而且变化不大。当我使用我当前的解决方案时,剩余时间会长时间增加,然后开始减少。
我正在寻找更好的解决方案。我能做些什么?
long totalTiles = ((((rightBottom.X) - (topLeft.X)) + 1) * (((rightBottom.Y) - (topLeft.Y)) + 1));
long currentTileProccessed = 0;
DateTime startTime = DateTime.Now;
for (long x = (topLeft.X); x <= (rightBottom.X); x++)
{
for (long y = (topLeft.Y); y <= (rightBottom.Y); y++)
{
**//Real job done here//**
TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (totalTiles - (currentTileProccessed + 1)) / (currentTileProccessed + 1));
this.Dispatcher.Invoke((Action)delegate () {
EstimatedTimeLeft_TextBlock.Text = "Days : " + timeRemaining.Days.ToString("D2") + ", Hours : " + timeRemaining.Hours.ToString("D2") + ", Minutes :" + timeRemaining.Minutes.ToString("D2") + ", Seconds :" + timeRemaining.Seconds.ToString("D2");
});
currentTileProccessed++;
}
}
解决方案
在这里,我使用 System.Diagnostics 中的 Stopwatch 来确定最后 100 个任务的平均时间,我将其乘以预期的任务总数减去已经运行的任务数。
注意:剩余时间仍然会增加,如果突然最后 100 个任务开始运行比之前的 10k 慢,这将重新调整您的剩余时间以匹配最近的运行。
long totalTiles = ((((rightBottom.X) - (topLeft.X)) + 1) * (((rightBottom.Y) - (topLeft.Y)) + 1));
long currentTileProccessed = 0;
Queue<long> taskTimes = new Queue<long>();
int taskTimeHistoryLimit = 100;
long taskTotal = (rightBottom.X - topLeft.X) * (rightBottom.Y - topLeft.Y);
Stopwatch watch = new Stopwatch();
long index = 0;
for (long x = (topLeft.X); x <= (rightBottom.X); x++)
{
for (long y = (topLeft.Y); y <= (rightBottom.Y); y++)
{
index++;
watch.Start();
//Real job done here//
watch.Stop();
taskTimes.Enqueue(watch.ElapsedTicks);
watch.Reset();
while (taskTimes.Count > taskTimeHistoryLimit)
{
taskTimes.Dequeue();
}
TimeSpan timeRemaining = new TimeSpan((taskTotal - index) * (long)taskTimes.Average());
this.Dispatcher.Invoke((Action)delegate () {
EstimatedTimeLeft_TextBlock.Text = "Days : " + timeRemaining.Days.ToString("D2") + ", Hours : " + timeRemaining.Hours.ToString("D2") + ", Minutes :" + timeRemaining.Minutes.ToString("D2") + ", Seconds :" + timeRemaining.Seconds.ToString("D2");
});
}
}
推荐阅读
- lua - 用特定的最大值和最小值修改表中的数字
- javascript - 用于处理 JSON 中“”的正则表达式匹配
- node.js - 如何修复 NodeJS 中的“重定向问题”错误?
- python - 发布到部署在heroku上的应用程序时请求为空
- dart - 如何追踪为什么 mixin 的一个成员在作用域模型中覆盖另一个成员
- python - 如何修复 Python 上 p2p 聊天应用程序的“IndexError: list index out of range”错误?
- python-2.7 - 带有 CeleryExecutor 的气流没有从气流.cfg 中选择 Celery 的配置集
- groovy - 将参数传递给 groovy 闭包
- vue.js - vue cli build 为什么会两次注入app.js、app.css、vendors.js和vendors.css?
- python - 根据规则 Pandas 数据框创建新列