shu*_*alo 10 c++ time c++-chrono
打印日志时,我希望每条消息都有一个时间戳,测量自程序启动以来的时间。最好以纳秒为单位,尽管毫秒也可以:
( 110 ns) Some log line
( 1220 ns) Another log line
( 2431 ns) Now for some computation...
(10357 ns) Error!
Run Code Online (Sandbox Code Playgroud)
据我了解,C++ chrono 库中有三种不同的时钟和另外两种 C 风格的时钟:
对于上述任务,每种方法的优点和缺点是什么?
How*_*ant 18
system_clock是一个与 UTC 保持时间(不包括闰秒)的时钟。每隔一段时间(也许一天几次),它就会进行少量调整,以使其与正确的时间保持一致。这通常通过 NTP 等网络服务来完成。这些调整通常为微秒量级,但可以在时间上向前或向后。实际上,该时钟的时间戳有可能(尽管不太可能也不常见)向后移动少量。除非被管理员滥用,否则system_clock不会因夏令时或更改计算机的本地时区等原因而大幅跳跃,因为它始终跟踪 UTC。
steady_clock就像秒表一样。它与任何时间标准都没有关系。它只是一直滴答作响。它可能无法保持完美的时间(没有时钟真的能保持完美的时间)。但它永远不会调整,尤其不会向后调整。它非常适合对短代码进行计时。但由于它永远不会被调整,因此它可能会随着时间的推移而发生漂移,system_clock以与 UTC 保持同步进行调整。
这归结为这样一个事实:steady_clock最适合短时间的计时。它通常还具有纳秒分辨率,但这不是必需的。并且system_clock最适合计时“长”时间,其中“长”非常模糊。但当然,几小时或几天就可以算作“长”,而一秒以下的持续时间则不算。如果您需要将时间戳与人类可读的时间(例如民用日历上的日期/时间)相关联,这system_clock是唯一的选择。
high_resolution_clock允许作为 或 的类型别名steady_clock,system_clock并且实际上始终如此。但有些平台别名为steady_clock,有些平台别名为system_clock。所以恕我直言,最好直接选择steady_clock,system_clock这样你就知道你会得到什么。
虽然没有具体说明,std::time但通常限制为秒的分辨率。所以对于需要亚秒级精度的情况完全无法使用。否则std::time跟踪 UTC(不包括闰秒),就像system_clock.
std::clock跟踪处理器时间,而不是物理时间。也就是说,当您的线程不忙于执行某些操作并且操作系统已将其停放时, 的测量std::clock将不会反映停机期间时间的增加。如果这就是您需要测量的内容,这可能非常有用。如果您在使用它时没有意识到您正在测量的是处理器时间,那可能会非常令人惊讶。
C++20 向库中添加了四个时钟<chrono>:
utc_clock与 类似system_clock,只不过它计算闰秒。time_point当您需要在闰秒插入点上减去两个 s,并且您绝对需要计算插入的闰秒(或其一小部分)时,这主要有用。
tai_clock测量自 1958-01-01 00:00:00 以来的秒数,并在该日期比 UTC 提前 10 秒。它没有闰秒,但每次将闰秒插入 UTC 时,TAI 和 UTC 的日历表示法就会相差一秒。
gps_clock对 GPS 时间系统进行建模。它测量自 1980 年 1 月第一个星期日 00:00:00 UTC 以来的秒数。与 TAI 一样,每次在 UTC 中插入闰秒,GPS 和 UTC 的日历表示法就会相差一秒。由于 GPS 和 TAI 处理 UTC 闰秒的方式相似,因此 GPS 的历法表示总是落后 TAI 19 秒。
file_clock是库使用的时钟filesystem,并且是产生chrono::time_point别名的时钟std::filesystem::file_time_type。
可以使用 C++20 中的一种新的命名转换来在、、和之间clock_cast进行转换。例如:time_pointsystem_clockutc_clocktai_clockgps_clockfile_clock
auto tp = clock_cast<system_clock>(last_write_time("some_path/some_file.xxx"));
Run Code Online (Sandbox Code Playgroud)
的类型tp是system_clock基于 - 的time_point,与 具有相同的duration类型(精度)file_time_type。