C++高精度计时的几种方法总结(测试函数运行时间)

 更新时间:2024年09月23日 10:10:37   作者:痛&快乐着  
本文介绍了C++中常用的几种程序计时方法,包括clock()函数、GetTickCount()、QueryPerformanceCounter()以及C++11中的chrono库函数,这篇文章主要介绍了C++高精度计时的几种方法,需要的朋友可以参考下

一、clock()函数——毫妙级

C系统调用方法,所需头文件ctime/time.h,即windows和linux都可以使用。

1、clock()返回类型为clock_t类型

2、clock_t实际为long 类型, typedef long clock_t

3、clock() 函数,返回从 开启这个程序进程 到 程序中调用clock()函数 时之间的CPU时钟计时单元(clock tick)数(挂钟时间),返回单位是毫秒

4、可以用常量CLOCKS_PER_SEC, 这个常量表示每一秒(per second)有多少个时钟计时单元

#include <time.h>   //引入头文件
void time1()
{
	clock_t start, end;
	start = clock();

	fun();  //需计时的函数

	end = clock();  
	cout << "elapsed time in clock = " << double(end - start) << "ms" << endl;  
}

二、GetTickCount()函数(精度16ms左右)——毫妙级

GetTickCount()是一个Windows API,所需头文件为<windows.h>。是通过计算从函数开始运行计时,直到函数运行结束所求出函数的运行时间。它返回从操作系统启动所经过的毫秒数,

此处需要注意的是,这个函数所求的的运行时间并非准确运行时间,不过相对来说比较准确,它的精度和CPU有关,一般精度在16ms左右,由于GetTickCount()返回值以32位的双字类型DWORD存储,所以它的存储最大值是(2^32-1) ms约为49.71天,一旦一个程序运行时间超过这个值,这个数字就会归为0。

#include <windows.h>   //引入头文件
void time2()
{
	DWORD t1, t2;
	t1 = GetTickCount();

	fun();  //需计时的函数

	t2 = GetTickCount();
	cout << "elapsed time in GetTickCount = " << double(t2 - t1) << "ms" << endl;
}

三、高精度时控函数QueryPerformanceCounter()——微妙级

原理:这里使用高精度时控函数QueryPerformanceFrequency(),QueryPerformanceCounter()
它们是两个精度很高的函数,精度单位为微秒。使用QueryPerformanceCounter()即可获取这个高精度计时器的值,但是由于机器的原因,它们实际上的精度会大幅度受到机器运作的影响,则必须向系统查询它们确切的运作频率QueryPerformanceFrequency()函数提供了这个功能,可以通过这一个函数来获取高精度计时器的运作频率(在一秒钟之内它的运作次数),用两次调用QueryPerformanceCounter()函数的结果做差除以QueryPerformanceFrequency()的运作频率即可求出在两次“时间获取”之间所经过的时间。在其中放入想要测量时间的算法代码,就可以得知算法的运行时长。

精度: 计算机获取硬件支持,精度比较高,可以通过它判断其他时间函数的精度范围。

//QueryPerformanceCounter()是一个Windows API,所需头文件为<windows.h>
#include <windows.h>   //引入头文件
void time3()
{
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	QueryPerformanceCounter(&t1);

	fun();  //需计时的函数

	QueryPerformanceCounter(&t2);
	double time = (double)(t2.QuadPart - t1.QuadPart) / (double)tc.QuadPart;
	cout << "elapsed time in QuadPart = " << time * 1000 << "ms" << endl;
}

四、高精度计时chrono函数——纳妙级

C++11 中的 chrono 库提供了精度最高为纳秒级的计时接口。由于是标准库中提供的功能,所以可以很好地跨平台使用。

下面来看一段使用 chrono 进行高精度计时的示例代码:

#include <iostream>
#include <chrono>
void time4()
{
	// 计时开始时间点
	// chrone 中常用的时钟类:
	// 		- std::chrono::high_resolution_clock
	//   	- std::chrono::system_clock
	//      - std::chrono::steady_clock
	// 三种时钟类有一些区别,其中 high_resolution_clock 精度最高
	auto start = std::chrono::high_resolution_clock::now();

	// 要计时的代码段
	fun();  
	// 计时结束时间点
	auto end = std::chrono::high_resolution_clock::now();

	// 计算运行时间, 时间单位:
	//      - std::chrono::seconds
	//      - std::chrono::milliseconds
	//      - std::chrono::microseconds
	//      - std::chrono::nanoseconds
	auto duration = std::chrono::duration_cast<std::chrono::microseconds> (end - start);

	// 输出时间(给定时间单位)
	cout << "elapsed time in chrono = " << duration.count()/1000.0 << "ms" << endl;
} 

其中,microseconds 表示微妙。除此之外,还有五种时间单位:hours, minutes, seconds, milliseconds, nanoseconds.

五、几种计时比较

#include <iostream>
#include <chrono>
#include <thread>
#include <time.h>
#include <windows.h>

using namespace std;

void fun()
{
	// 睡眠100ms
	std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
void compareTime()
{
	LARGE_INTEGER t1, t2, tc;
	QueryPerformanceFrequency(&tc);
	
	
	clock_t start, end;

	DWORD t11, t12;
	start = clock();
	t11 = GetTickCount();
	QueryPerformanceCounter(&t1);
	auto start1 = std::chrono::high_resolution_clock::now();

	fun();  //需计时的函数

	end = clock();
	t12 = GetTickCount();
	QueryPerformanceCounter(&t2);
	auto end1 = std::chrono::high_resolution_clock::now();
	double time = (double)(t2.QuadPart - t1.QuadPart) / (double)tc.QuadPart;
	auto duration = std::chrono::duration_cast<std::chrono::microseconds> (end1 - start1);

	cout << "elapsed time in clock = " << double(end - start) << "ms" << endl;
	cout << "elapsed time in GetTickCount = " << double(t12 - t11) << "ms" << endl;
	cout << "elapsed time in QuadPart = " << time * 1000 << "ms" << endl;
	cout << "elapsed time in chrono = " << duration.count() / 1000.0 << "ms" << endl;
}

六、linux下的计时函数gettimeofday()-未测试

gettimeofday() linux环境下的计时函数,int gettimeofday ( struct timeval * tv , struct timezone * tz ),gettimeofday()会把目前的时间由tv所指的结构返回,当地时区的信息则放到tz所指的结构中.

//timeval结构定义为:
struct timeval{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
//timezone 结构定义为:
struct timezone{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};

这个函数获取从1970年1月1日到现在经过的时间和时区(UTC时间),(按照linux的官方文档,时区已经不再使用,正常应该传NULL)。

调用代码:

#include <sys/time.h>   //引入头文件
int main()
{
    struct timeval t1,t2;
    double timeuse;
    gettimeofday(&t1,NULL);
 
    fun();
 
    gettimeofday(&t2,NULL);
    timeuse = (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1000000.0;
 
    cout<<"time = "<<timeuse<<endl;  //输出时间(单位:s)
}

参考文献

C++下四种常用的程序运行时间的计时方法总结

C++中几种测试程序运行时间的方法

到此这篇关于C++高精度计时的几种方法的文章就介绍到这了,更多相关C++高精度计时方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 利用C语言绘制一个正方体

    利用C语言绘制一个正方体

    这篇文章主要为大家详细介绍了如何利用C语言绘制一个正方体,文中的示例代码讲解详细,具有一定的学习和借鉴价值,感兴趣的小伙伴可以学习一下
    2023-01-01
  • C++实现简单贪吃蛇小游戏

    C++实现简单贪吃蛇小游戏

    这篇文章主要为大家详细介绍了C++实现简单贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • 详解C/C++性能优化背后的方法论TMAM

    详解C/C++性能优化背后的方法论TMAM

    开发过程中我们多少都会关注服务的性能,然而性能优化是相对比较困难,往往需要多轮优化、测试,属于费时费力,有时候还未必有好的效果。但是如果有较好的性能优化方法指导、工具辅助分析可以帮助我们快速发现性能瓶颈所在,针对性地进行优化,可以事半功倍
    2021-06-06
  • QT基于TCP实现网络聊天室程序

    QT基于TCP实现网络聊天室程序

    这篇文章主要为大家详细介绍了QT基于TCP实现网络聊天室程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++实现位图排序实例

    C++实现位图排序实例

    这篇文章主要介绍了C++实现位图排序,是比较重要的排序算法,需要的朋友可以参考下
    2014-08-08
  • C++实现反转链表的两种方法

    C++实现反转链表的两种方法

    本文主要介绍了C++实现反转链表的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • C语言中单目操作符++、–的实例讲解

    C语言中单目操作符++、–的实例讲解

    C语言的操作符共分为算术操作符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符,逗号表达式,下表引用、函数调用和结构成员这10大类,这篇文章主要给大家介绍了关于C语言中单目操作符++、–的相关资料,需要的朋友可以参考下
    2021-12-12
  • C++ 非递归实现二叉树的前中后序遍历

    C++ 非递归实现二叉树的前中后序遍历

    本文将结合动画和代码演示如何通过C++ 非递归实现二叉树的前中后序的遍历,代码具有一定的价值,感兴趣的同学可以学习一下
    2021-11-11
  • C语言形参和实参的区别详解

    C语言形参和实参的区别详解

    在函数定义和调用过程中,形参和实参是非常重要的概念,本文主要介绍了C语言形参和实参的区别,具有一定的参考价值,感兴趣的可以了解一下
    2023-05-05
  • C++中std::thread{}和std::thread()用法

    C++中std::thread{}和std::thread()用法

    std::thread{}和std::thread()在C++中都可以用于创建线程对象,但std::thread{}作为C++11引入的统一初始化,更推荐使用,因为它更安全、更易读,且避免了隐式类型转换
    2024-11-11

最新评论