转自:
https://blog.csdn.net/CAIYUNFREEDOM/article/details/75388111
http://sodino.com/2015/03/20/c-time-micro-nano/

获取时间戳(s 级)

1
2
3
4
//in <time.h>
time_t t= time(NULL);
std::cout<<" s秒级 ----:";
std::cout<<t<<endl;

Linux 下获取系统时间的时间戳(μs, ns 级)

unistd.hsys/time.h 存在于 GCC,但是 Visual Studio 没有这两个头文件。Dev-C++ 可以使用该方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>  
#include <sys/time.h>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <unistd.h>

using namespace std;
time_t clocktime()
{
//in <sys/time.h>
struct timeval tv;
gettimeofday(&tv,NULL);
std::cout<<"10e6 微秒级s ----:";
std::cout<<tv.tv_sec<<"s,"<<tv.tv_usec<<"微秒"<<endl;

//in <time.h>
struct timespec tn;
cout<<"----";
clock_gettime(CLOCK_REALTIME, &tn);

std::cout<<"10e9 纳秒级s ----:";
std::cout<<tn.tv_sec<<"s,"<<tn.tv_nsec<<"纳秒"<<endl;


struct timespec current_time,last_time;
double aa=1.1234567891;
printf("double %.12f\n",aa);
cout<<"----";
clock_gettime(CLOCK_REALTIME, &last_time);
sleep(1);
std::cout<<last_time.tv_sec<<","<<last_time.tv_nsec<<endl;
clock_gettime(CLOCK_REALTIME, ¤t_time);
std::cout<<current_time.tv_sec<<","<<current_time.tv_nsec<<","<<pow(10,-9)<<endl;
double delta_time = (current_time.tv_sec - last_time.tv_sec)+ (current_time.tv_nsec - last_time.tv_nsec)*pow(10,-9);
printf("double %.12f\n",delta_time);

}
int main( ){
clocktime();
return 0;
}

测试如下:

1
2
3
4
5
6
10e6 微秒级s ----:1500448195s,315233微秒
----10e9 纳秒级s ----:1500448195s,315235598纳秒
double 1.123456789100
----1500448195,315242687
1500448196,315388886,1e-09
double 1.000146199000

ms 级时间的运算

由于 C 语言既没有成员函数,也没有引用,
于是,减法函数居然是在宏定义里实现的:

1
2
3
4
5
6
7
8
9
#define    timersub(tvp, uvp, vvp)                        \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)

还行。

可以调用的函数还有如下:

1
2
3
4
5
timersub(tvp, uvp, vvp) //v = t - u
timerclear() // 清除时间
timerisset() // 结构体中是否有设置时间值
timercmp() // 比较时间值大小
timeradd() // 两个时间值相加

MSVC 下获取本程序运行的时间(μs 级)

参考链接:https://docs.microsoft.com/zh-cn/windows/win32/sysinfo/acquiring-high-resolution-time-stamps

在测时间戳上,微软使用的是它的 API: QueryPerformanceCounter(QPC,查询性能计数器?),精确度在 1μs 内。

网站上还直接给出了可用的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<profileapi.h>

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

但是在 VS 2017 上直接编译会报错:#error No Target Architecture

Google 以后发现,需要在 项目 - (项目名)属性 - 配置属性 - C/C++ - 预处理器 - 预处理器定义 中加入 _X86_(32 位应用程序) 或 _AMD64_ (64 位应用程序),再编译即可。

最后 ElapsedMicroseconds.QuadPart 即是以微秒为单位的 long long 时间间隔变量。

获取本程序运行的时间(s 级)

就是使用 clocks 啦。Just use clocks. However, accuracy is not guaranteed, and because of CPU problems, there are errors that can only be used for rough estimation. The s level should be no problem.但是不保证精度,而且因为 CPU 问题,存在误差,只能用于粗略估计。s 级应该是没有问题的。

1
2
#include<time.h>
float t = clock() * 1.0 / CLOCKS_PER_SEC

Linux 下获取本程序运行的时间(ns 级)

由于要获取 pid,挺麻烦的。
需要用到的函数有:

1
2
3
4
5
6
7
8
#include<inistd.h>
pid_t getpid();

#include <time.h>
int clock_getcpuclockid(pid_t pid, clockid_t *clock_id);

#include<time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);

写成代码就是:

1
2
3
4
clockid_t clock_id;
timespec tp;
clock_getcpuclockid(getpid(), &clock_id)
clock_gettime(clock_id, &tp);

貌似不是特别常用,因此不再深入。