用于记录时间戳的不同 C++ 时钟的优缺点是什么?
What are the pros & cons of the different C++ clocks for logging time stamps?
打印我的日志时,我希望每条消息都有一个时间戳,测量自程序启动以来的时间。最好以纳秒为单位,尽管毫秒也可以:
( 110 ns) Some log line
( 1220 ns) Another log line
( 2431 ns) Now for some computation...
(10357 ns) Error!
据我了解,C++ chrono 库中有三种不同的时钟和另外两种 C 风格的时钟:
- std::chrono::high_resolution_clock
- std::chrono::system_clock
- std::chrono::steady_clock
- std::time
- std::clock
上述任务各自的优缺点是什么?
system_clock
是一个与 UTC(不包括闰秒)保持时间的时钟。每隔一段时间(可能一天几次),它会进行少量调整,以使其与正确的时间保持一致。这通常通过 NTP 等网络服务来完成。这些调整通常以微秒为单位,但时间可以向前或向后。这个时钟的时间戳实际上有可能(虽然不太可能也不常见)向后移动一点点。除非被管理员滥用,否则 system_clock
不会按总量跳跃,例如由于夏令时或更改计算机的本地时区,因为它始终跟踪 UTC。
steady_clock
就像一个秒表。它与任何时间标准都没有关系。它一直在滴答作响。它可能不会保持完美的时间(没有时钟确实如此)。但它永远不会调整,尤其是不会倒退。它非常适合计时短代码位。但由于它从未得到调整,它可能会随着时间的推移相对于 system_clock
进行漂移,而 system_clock
已调整为与 UTC 保持同步。
这归结为 steady_clock
最适合短时计时。它通常还具有纳秒分辨率,但这不是必需的。 system_clock
最适合计时“长”时间,其中“长”非常模糊。但可以肯定的是,数小时或数天符合“长”的条件,而低于一秒的持续时间则不算。如果您需要将时间戳与人类可读时间相关联,例如民用日历上的 date/time,那么 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
跟踪处理器时间,而不是物理时间。也就是说,当您的线程不忙于做某事并且 OS 已将其停放时,std::clock
的测量值将不会反映该停机期间增加的时间。如果这是您需要衡量的,这将非常有用。如果您在使用它时没有意识到您正在测量的是处理器时间,那可能会非常令人惊讶。
C++20 的新增功能
C++20 向 <chrono>
库添加了四个时钟:
utc_clock
与 system_clock
类似,只是它计算的是闰秒。当您需要在闰秒插入点上减去两个 time_point
并且您绝对需要计算插入的闰秒(或其分数)时,这主要有用。
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
库使用的时钟,也是产生别名为 std::filesystem::file_time_type
的 chrono::time_point
的时钟。
可以使用 C++20 中名为 clock_cast
的新命名转换在 system_clock
、utc_clock
、[=34= 的 time_point
之间进行转换]、gps_clock
和 file_clock
。例如:
auto tp = clock_cast<system_clock>(last_write_time("some_path/some_file.xxx"));
tp
的类型是基于 system_clock
的 time_point
,与 file_time_type
具有相同的 duration
类型(精度)。
打印我的日志时,我希望每条消息都有一个时间戳,测量自程序启动以来的时间。最好以纳秒为单位,尽管毫秒也可以:
( 110 ns) Some log line
( 1220 ns) Another log line
( 2431 ns) Now for some computation...
(10357 ns) Error!
据我了解,C++ chrono 库中有三种不同的时钟和另外两种 C 风格的时钟:
- std::chrono::high_resolution_clock
- std::chrono::system_clock
- std::chrono::steady_clock
- std::time
- std::clock
上述任务各自的优缺点是什么?
system_clock
是一个与 UTC(不包括闰秒)保持时间的时钟。每隔一段时间(可能一天几次),它会进行少量调整,以使其与正确的时间保持一致。这通常通过 NTP 等网络服务来完成。这些调整通常以微秒为单位,但时间可以向前或向后。这个时钟的时间戳实际上有可能(虽然不太可能也不常见)向后移动一点点。除非被管理员滥用,否则 system_clock
不会按总量跳跃,例如由于夏令时或更改计算机的本地时区,因为它始终跟踪 UTC。
steady_clock
就像一个秒表。它与任何时间标准都没有关系。它一直在滴答作响。它可能不会保持完美的时间(没有时钟确实如此)。但它永远不会调整,尤其是不会倒退。它非常适合计时短代码位。但由于它从未得到调整,它可能会随着时间的推移相对于 system_clock
进行漂移,而 system_clock
已调整为与 UTC 保持同步。
这归结为 steady_clock
最适合短时计时。它通常还具有纳秒分辨率,但这不是必需的。 system_clock
最适合计时“长”时间,其中“长”非常模糊。但可以肯定的是,数小时或数天符合“长”的条件,而低于一秒的持续时间则不算。如果您需要将时间戳与人类可读时间相关联,例如民用日历上的 date/time,那么 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
跟踪处理器时间,而不是物理时间。也就是说,当您的线程不忙于做某事并且 OS 已将其停放时,std::clock
的测量值将不会反映该停机期间增加的时间。如果这是您需要衡量的,这将非常有用。如果您在使用它时没有意识到您正在测量的是处理器时间,那可能会非常令人惊讶。
C++20 的新增功能
C++20 向 <chrono>
库添加了四个时钟:
utc_clock
与 system_clock
类似,只是它计算的是闰秒。当您需要在闰秒插入点上减去两个 time_point
并且您绝对需要计算插入的闰秒(或其分数)时,这主要有用。
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
库使用的时钟,也是产生别名为 std::filesystem::file_time_type
的 chrono::time_point
的时钟。
可以使用 C++20 中名为 clock_cast
的新命名转换在 system_clock
、utc_clock
、[=34= 的 time_point
之间进行转换]、gps_clock
和 file_clock
。例如:
auto tp = clock_cast<system_clock>(last_write_time("some_path/some_file.xxx"));
tp
的类型是基于 system_clock
的 time_point
,与 file_time_type
具有相同的 duration
类型(精度)。