改进基于<chrono>
Improving a timer class based on <chrono>
我有以下Timer类来简化获取自epoch以来经过的时间:
#include <chrono>
class Timer {
public:
void start(void);
template <typename duration_type>
const duration_type time_elapsed(void);
private:
std::chrono::high_resolution_clock::time_point epoch;
};
void Timer::start(void) {
epoch = std::chrono::high_resolution_clock::now();
}
template <typename duration_type>
const duration_type Timer::time_elapsed(void) {
return std::chrono::duration_cast<duration_type>(std::chrono::high_resolution_clock::now() - epoch);
}
int main(void) {
Timer timer;
timer.start();
// pointless loop to cause a delay
for (int x = 1; x < 1000000; ++x) {
x * x * x;
}
std::chrono::nanoseconds elapsed = timer.time_elapsed<std::chrono::nanoseconds>();
std::cout << elapsed.count() << std::endl;
return 0;
}
我有一种感觉,我把Timer::time_elaped()作为一个模板函数,这使我的类过于复杂了,理想情况下,我想把它的用法简化为:
std::chrono::nanoseconds elapsed = timer.time_elapsed();
std::cout << elapsed.count() << std::endl;
我修复了代码中的一些内容,并添加了std::chrono
的正确用法。更改列表包括:
- 我从函数调用中删除了所有
(void)
参数,因为它不是C++方式:-) - 我还从
main()
中删除了C++中不需要的return 0;
,因为编译器会为您放置它 - 我键入了一个时钟,因为现在在当前的实现中可能很难找到一个高质量的时钟。请在此处查看我的答案。基本上,现在您可能想要使用自定义时钟,并且由于
typedef
,重构在未来可能会更容易 - 我把你的等待循环改成了C++11睡眠接口(如果你愿意,你可以在那里随机分配一些持续时间——也可以用C++11:-)。在这种情况下不需要这种更改,但它很好地展示了
std::chrono
在线程库中的使用 - 我把你的方法实现放在一个类中,让编译器有机会内联它们。或者,您可以在类之外的实现中使用
inline
关键字explicity - 我做了你的
time_elapsed()
方法const
- 我从
time_elapsed()
方法的返回值中删除了不必要的const
,另一方面在使用该方法时添加了它,因为在那个确切的地方const
就足够了 - 最后但同样重要的是,我修改了您的
time_elapsed()
方法,以在return
中返回时钟的本机分辨率。这是一个更好的解决方案,因为您永远不会在这里丢失数据。当向特定单元(即我们)中的用户提供数据时,您可能想要放松它。你必须在那里使用duration_cast
来告诉编译器你同意丢失一些数据,我们的分辨率对你来说已经足够了
我希望下面的代码和上面的更改会让你感兴趣。
#include <chrono>
#include <thread>
#include <iostream>
using namespace std::chrono;
class Timer {
public:
typedef high_resolution_clock Clock;
void start()
{ epoch = Clock::now(); }
Clock::duration time_elapsed() const
{ return Clock::now() - epoch; }
private:
Clock::time_point epoch;
};
int main() {
Timer timer;
timer.start();
// sleep some time
std::this_thread::sleep_for(microseconds(40));
const auto elapsed = timer.time_elapsed();
std::cout << duration_cast<microseconds>(elapsed).count() << "us" << std::endl;
}
顺便说一句,我不想玩类接口(我已经做了太多的更改)。如果你还没有绑定到那个接口,我建议你使用@sehe建议的接口。但不要将该double
用作返回值;-)
返回一个助手类,该类存储now-egic(),并根据经过的时间对运算符T执行高精度强制转换。或者,有一个time_elapsed_in_units<T>
方法,看起来像你的时间流逝,然后让时间流逝返回一个结构,该结构以单位调用运算符T.
通过重载helper类的运算符T,可以隐式地检测被调用方想要的类型。
相关文章:
- 从持续时间构造std::chrono::system_clock::time_point
- 如何在c++迭代器类型中包装std::chrono
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- EASTL矢量<向量<int>>连续的
- 使用 memcpy() 复制到 std::chrono::milliseconds 会给出错误 -Werror=clas
- std::multimap<std::chrono::milliseconds, T>::rbegin 在 MSVS-13 中指向 end()?
- 如何在C++中将 chrono::秒转换为 HH:MM:SS 格式的字符串?
- C++ Chrono 确定一天是否是周末?
- std::adjacent_difference with std::chrono time_point
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 是否确保 2 个连续的 std::chrono::steady_clock::now() 不相等?
- std::chrono::d uration 可以按秒初始化,但不能按毫秒初始化?
- chrono::month 和 chrono::month 有什么区别
- 比较两个 std::chrono::time_point 实例时出错
- 来自 std::chrono 的编译器警告,但未被使用
- 从编译时已知的日历日期创建"std::chrono::time_point"
- std::chrono::time_point from std::string
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 如何在不使用 std::tm 和 mktime() 的情况下为给定日历日期创建 chrono::time_point 对