源码+注释
//
// Created by Lenovo on 2022-05-28-下午 2:09.
// 作者:小象
// 版本:1.0
//
#include "stdio.h"
#include "stdarg.h"
#include "unistd.h" // sleep
#include "sys/timeb.h"
#include "sys/time.h"
#include "confpriv.h"
#include "time.h" // clock, time, clock_gettime
/**
* <h2>进程、内核空间、用户空间、代码段... 计时器</h2>
* <h3>
* 基本单位转换:<br>
* 1s = 1000ms 1ms = 1000us 1us = 1000ns
* </h3>
* @return 0
*/
int main() {
// 把需要测试的方式放进这里即可运行
}
/**
* <h3>推荐方式,可以测试某一段代码所用时间(精度:纳秒)</h3>
* <h3>优点:精度最高,最适合测试代码段运行时间的方式</h3>
*/
void timer_01() {
/*
* timespec 结构体底层源码解析(types.h)
*
* struct timespec {
* time_t tv_sec; // 精度:秒
* long tv_nsec; // 精度:纳秒
* };
*
*/
struct timespec start;
struct timespec end;
// 开始时间
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
long i = 0;
while (i < 10e6) {
i++;
}
// 结束时间
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
// 总耗时
// printf("%lf\n", (end.tv_nsec - start.tv_nsec) / 1.0);
// printf("%lf", (end.tv_sec - start.tv_sec) * 1000.0);
// 转化为 ms 为单位(但是精度可以直接到ns级别)
double start_ms = start.tv_sec * 1000.0 + start.tv_nsec / 1000000.0;
double end_ms = end.tv_sec * 1000.0 + end.tv_nsec / 1000000.0;
printf("执行时间:%.8lf ms\n", end_ms - start_ms); // 15.62500000 ms
}
/**
* <h3>不推荐方式,可以测试某一段代码所用时间(精度:秒)</h3>
* <h3>缺点:容易出现溢出问题,测量多进程不公平</h3>
*/
void timer_02() {
// 开始时间
time_t start_s = time(NULL);
long i = 0;
while (i < 10e6) {
i++;
}
// 结束时间
time_t end_s = time(NULL);
// 总耗时
printf("执行时间:%lld s\n", end_s - start_s); // 0 s
}
/**
* <h3>不推荐方式,可以测试某一段代码所用时间(精度:微秒)</h3>
* <h3>缺点:容易出现溢出问题,测量多进程不公平</h3>
*/
void timer_03() {
/*
* timeval 结构体底层源码解析(timeval.h)
*
* struct timeval
* {
* long tv_sec; // 精度:秒
* long tv_usec; // 精度:微秒
* };
*
*/
struct timeval start_us;
struct timeval end_us;
// 开始时间
gettimeofday(&start_us, NULL);
long i = 0;
while (i < 10e6) {
i++;
}
// 结束时间
gettimeofday(&end_us, NULL);
// 总耗时
// 转化为 ms 为单位(但是精度可以直接到us级别)
double start_ms = start_us.tv_sec * 1000.0 + start_us.tv_usec / 1000.0;
double end_ms = end_us.tv_sec * 1000.0 + end_us.tv_usec / 1000.0;
printf("执行时间:%lf ms\n", end_ms - start_ms); // 13.962891 ms
}
/**
* <h3>不推荐方式,只能测试程序运行时间(精度:毫秒)</h3>
* <h3>缺点:容易出现溢出问题</h3>
*/
void timer_04() {
long i = 0;
while (i < 10e6) {
i++;
}
clock_t ticks = clock();
double secs = (double) ticks / CLOCKS_PER_SEC;
printf("执行时间:%lf ms\n", secs * 1000); // 13.000000 ms
}
/**
* <h3>推荐方式,可以测试某一段代码所用时间(精度:微秒)</h3>
* <h3>优点:测试环境适应能力强</h3>
*/
void timer_05() {
union _LARGE_INTEGER time_start; //开始时间
union _LARGE_INTEGER time_over; //结束时间
LARGE_INTEGER f; // 计时器频率
QueryPerformanceFrequency(&f);
double dqFreq = (double) f.QuadPart; // 计时器频率
QueryPerformanceCounter(&time_start); // 计时开始
long i = 0;
while (i < 10e6) {
i++;
}
QueryPerformanceCounter(&time_over); // 计时结束
// 乘以1000000把单位由秒化为微秒,精度为1000 000/(cpu主频)微秒
double run_time = 1000000.0 * (time_over.QuadPart - time_start.QuadPart) / dqFreq;
printf("执行时间:%lf ms\n", run_time / 1000.0); // 13.992400 ms
}
/**
* <h3>不推荐方式,可以测试某一段代码所用时间(精度:毫秒)</h3>
*/
void timer_06() {
clock_t start, finish;
long i = 0;
while (i < 10e6) {
i++;
}
finish = clock(); // 底层: clock_t __cdecl clock(void);
double totalTime = (double) (finish - start);
printf("%lf ms\n", totalTime); // 13.000000 ms
}