#include <time.h>
int clock_gettime (clockid_t clock_id, struct timespec *tp)
获取当前 clock_id 的时钟值并存储在 tp 中。
其中 tp 是一个 timespec 结构体,在 time.h 头文件中定义:
#include <time.h>:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
clock_id 是识别系统时钟的 ID,常用的定义有以下几种:
adjtime()
和 NTP 执行的增量调整的影响。在系统休眠(suspend)时,CLOCK_MONOTONIC 会停止增加。可以通过「
man 3 clock_gettime
」命令查阅 Linux 手册获取 clock_id 更详细信息。
我们通过以下示例来展示程序运行耗时的计算方法:
#include <time.h>
int main(int argc, char const *argv[])
{
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
func_or_code_here(); // your code ...
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
long elapsed_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1e6;
return 0;
}
在上面的示例中,通过 clock_gettime()
函数获取运行时刻的实际时间并存储在 start
与 end
两个变量中,然后计算经过的时间(毫秒),最后得出函数运行耗时。
以下是一种 C++ 的封装方式,文件名为 timer.h,仅供参考:
#include <time.h>
class Timer {
public:
Timer() {
reset();
}
~Timer() = default;
long elapsed_sec() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_end);
return (_end.tv_sec - _start.tv_sec) + (_end.tv_nsec - _start.tv_nsec) / 1e9;
}
long elapsed_ms() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_end);
return (_end.tv_sec - _start.tv_sec) * 1000 + (_end.tv_nsec - _start.tv_nsec) / 1e6;
}
long elapsed_us() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_end);
return (_end.tv_sec - _start.tv_sec) * 1e6 + (_end.tv_nsec - _start.tv_nsec) / 1000;
}
long elapsed_ns() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_end);
return (_end.tv_sec - _start.tv_sec) * 1e9 + (_end.tv_nsec - _start.tv_nsec);
}
void reset() {
clock_gettime(CLOCK_MONOTONIC_RAW, &_start);
}
private:
struct timespec _start;
struct timespec _end;
};
在以上的封装过程中,在 Timer
类中定义了 _start
与 _end
成员变量,用于存储开始时间与结束时间,Timer
类提供了计算耗时的秒(elapsed_sec
),毫秒(elapsed_ms
),微秒(elapsed_us
),纳秒(elapsed_ns
)的成员函数。同时提供了 reset
函数用于重新计时。在这里我们可以通过以下示例来更好地理解 Timer
的用法:
#include <iostream>
#include "timer.h"
int main(int argc, char const *argv[])
{
Timer t;
func_or_code_here(); // your code ...
long elapsed_ms = t.elapsed_ms();
return 0;
}