有没有函数可以将纳秒转换为 std :: string,比如说“3m12s”?
No.但我会告诉你如何轻松地做到这一点。
我应该使用std ::计时:: steady_clock ::现在()每次我更新 我的进度条,并减去从_begin确定TIME_LEFT?
是的。
是否有更好的算法来确定TIME_LEFT
是。见下文。
编辑
我本来误解“滴答”为“时钟滴答”,当在现实中“滴答”有工作的单位和_ticks_occurred/_total_ticks
可以解释为%JOB_DONE。所以我已经相应地改变了建议的progress_bar
。
我相信公式:
time_left = (time_taken/_total_ticks) * (_total_ticks - _ticks_occured)
不正确。它没有通过一个完整性检查:如果_ticks_occured == 1
和_total_ticks
很大,那么time_left
大约等于(好,略少)time_taken
。这没有意义。
我重写上述方程为:
time_left = time_taken * (1/percent_done - 1)
其中
percent_done = _ticks_occurred/_total_ticks
现在,作为percent_done
接近零时,time_left
接近无穷大,并且当percent_done
接近1,'time_left
接近0。当percent_done
是10%,time_left
是9*time_taken
。这符合我的预期,假设每工作时间成本大致为线性时间成本。
class progress_bar
{
public:
progress_bar(uint64_t ticks)
: _total_ticks(ticks), _ticks_occurred(0),
_begin(std::chrono::steady_clock::now())
// ...
{}
void tick()
{
using namespace std::chrono;
// test to see if enough progress has elapsed
// to warrant updating the progress bar
// that way we aren't wasting resources printing
// something that hasn't changed
if (/* should we update */)
{
// somehow _ticks_occurred is updated here and is not zero
duration time_taken = Clock::now() - _begin;
float percent_done = (float)_ticks_occurred/_total_ticks;
duration time_left = time_taken * static_cast<rep>(1/percent_done - 1);
minutes minutes_left = duration_cast<minutes>(time_left);
seconds seconds_left = duration_cast<seconds>(time_left - minutes_left);
}
}
private:
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef Clock::rep rep;
std::uint64_t _total_ticks;
std::uint64_t _ticks_occurred;
time_point _begin;
//...
};
只要你可以在std :: chrono :: durations中进行交通。那样<chrono>
为你做了所有的转换。 typedefs可以减少长名称的打字。把时间分成几分钟和几秒就像上面显示的一样简单。
由于bames53在他的答案中提到,如果你想使用我的<chrono_io>
设施,那也很酷。你的需求可能很简单,你不想。这是一个判断呼吁。 bames53的回答是一个很好的答案。我认为这些额外的细节可能也有帮助。
编辑
我意外地留的错误在上面的代码。而不是仅仅修补上面的代码,我认为指出错误并展示如何使用<chrono>
来修复它是个好主意。
的错误是在这里:
duration time_left = time_taken * static_cast<rep>(1/percent_done - 1);
这里:
typedef Clock::duration duration;
在实践steady_clock::duration
通常基于整型。 <chrono>
称之为rep
(表示的简写)。并且当percent_done
大于50%时,乘以time_taken
的因子将小于1.并且当rep
是整数时,该因子被转换为0.因此,这个progress_bar
在前50%期间仅表现良好并且预测0时间在过去的50%左右。
解决这个问题的关键在于基于浮点数而不是整数的流量duration
。 <chrono>
使这非常容易做到。
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::period period;
typedef std::chrono::duration<float, period> duration;
duration
现在具有相同的刻度周期作为steady_clock::duration
但使用float
用于表示。这些修复再次
duration time_left = time_taken * (1/percent_done - 1);
这里是全包:现在对于time_left
计算可以不指定的static_cast
class progress_bar
{
public:
progress_bar(uint64_t ticks)
: _total_ticks(ticks), _ticks_occurred(0),
_begin(std::chrono::steady_clock::now())
// ...
{}
void tick()
{
using namespace std::chrono;
// test to see if enough progress has elapsed
// to warrant updating the progress bar
// that way we aren't wasting resources printing
// something that hasn't changed
if (/* should we update */)
{
// somehow _ticks_occurred is updated here and is not zero
duration time_taken = Clock::now() - _begin;
float percent_done = (float)_ticks_occurred/_total_ticks;
duration time_left = time_taken * (1/percent_done - 1);
minutes minutes_left = duration_cast<minutes>(time_left);
seconds seconds_left = duration_cast<seconds>(time_left - minutes_left);
std::cout << minutes_left.count() << "m " << seconds_left.count() << "s\n";
}
}
private:
typedef std::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::period period;
typedef std::chrono::duration<float, period> duration;
std::uint64_t _total_ticks;
std::uint64_t _ticks_occurred;
time_point _begin;
//...
};
没有什么像一个小测试... ;-)
“打勾”的原因是为了表示进度,即:我有100万次操作(滴答)完成。从我可以告诉助推有一个'chrono_io'。你会推荐使用它吗? – nerozehl 2012-03-03 00:26:41
哦,“嘀嗒”代表一个工作单位,而不是时间单位?如果是这样,我误解了你的问题。我误读了“时钟滴答”。增强''是我的''的授权副本。如果您觉得有帮助,应该可以使用。对于未来的标准,我建议'',所以最好有反馈意见。 –
2012-03-03 00:43:13
是蜱是一个工作单位..我想我应该更清楚,我对此感到抱歉。非常感谢你! :) – nerozehl 2012-03-03 00:52:43