前置
C++ 标准:C++11
头文件:<chrono>
简介
namespace std::chrono 中提供了三(两)种可用的时钟:std::chrono::_V2::steady_clock、std::chrono::_V2::system_clock、std::chrono::_V2::high_resolution_clock。
这之中,steady_clock 提供精度较高的稳定时钟,system_clock 提供精度更高但随系统时间变化的时钟。high_resolution_clock “表示实现提供的拥有最小计次周期的时钟;它可以是 system_clock 或 steady_clock 的别名,或第三个独立时钟。”(来源,有调整)
具体地,在 Intel(R) Core(TM) i5-9500T CPU @ 2.20GHz 的 CPU 环境下使用 Windows 10 Pro 21H2 操作系统的 g++ 11.2.0 编译出的 steady_clock 具有 100 ns 的精度,system_clock 具有 1 ns 的精度。[1]
本文主要讨论如何使用 steady_clock 实现计时。
[1] g++ -v 的输出:
1 2 3 4 5 6 7 8
   | Using built-in specs. COLLECT_GCC=E:\qidirj\RedPanda-Cpp\MinGW64\bin\g++.exe COLLECT_LTO_WRAPPER=E:/qidirj/RedPanda-Cpp/MinGW64/bin/../libexec/gcc/x86_64-w64-mingw32/11.2.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-11.2.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64 --enable-host-shared --disable-multilib --enable-languages=c,c++,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpc=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-isl=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev1, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/lib -L/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/lib -L/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/lib ' LD_FOR_TARGET=/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/bin/ld.exe --with-boot-ldflags=' -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc' Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (x86_64-posix-seh-rev1, Built by MinGW-W64 project)
   | 
 
原型
std::chrono::steady_clock
1 2 3 4 5 6 7 8 9 10 11 12
   | struct steady_clock {   typedef chrono::nanoseconds				duration;   typedef duration::rep					rep;   typedef duration::period					period;   typedef chrono::time_point<steady_clock, duration>	time_point;
    static constexpr bool is_steady = true;
    static time_point   now() noexcept; };
   | 
 
std::chrono::time_point_cast
1 2 3 4 5 6 7 8
   |    template<typename _ToDur, typename _Clock, typename _Dur>      constexpr typename enable_if<__is_duration<_ToDur>::value, 			   time_point<_Clock, _ToDur>>::type      time_point_cast(const time_point<_Clock, _Dur>& __t)      { typedef time_point<_Clock, _ToDur>			__time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch()));      }
   | 
 
std::chrono::_V2::steady_clock::time_point::time_since_epoch()
1 2 3
   | constexpr duration time_since_epoch() const { return __d; }
   | 
 
用法
获取当前相对时间
1
   | chrono::time_point_cast<chrono::nanoseconds>(chrono::steady_clock::now()).time_since_epoch()
   | 
 
chrono::steady_clock::now() 获取相对于一定时间点的当前时间,这个时间点可能是系统启动的时间、UNIX 时间起点等等。
接着,利用 chrono::time_point_cast<chrono::nanoseconds>() 将这个时间转换为纳秒形式,用 time_since_epoch 获取到相对时间。
求时间差
以上的表达式返回 std::chrono::_V2::steady_clock::duration 类型,其有 count() 成员函数,返回时间的整型形式,一般为 long long 类型。这之后,可以利用两个 duration 的 count 之差算出时间差,注意单位为纳秒。
实现计时
保存一个 std::chrono::_V2::steady_clock::duration start,在开始时将当前时间传入 start,则在任何时刻可以作差取到时间。