CC++ 程序计时方法的总结(windows API下)

C/C++ 程序计时方法的总结(Windows)

1.time.h下的方法

1.1 C语言下的time()函数

C语言下使用time()函数,可以进行秒级的计时.

头文件为 time.h .

函数原型为 time_t time(time_t * timer)

函数功能为 返回以格林尼治时间(GMT)为标准(即国际标准时)1970年1月1日 00:00:00 直至当下,所过去的秒数. 使用time()函数结合其他函数(如 localtime, gmtime, asctime, ctime)可以获得当前系统时间或标准时间.

需要使用difftime(t2, t1)的方式,而不是t2-t1的方式来计算时间间隔,因为C标准中并没有对time_t的单位强制规定为秒,而difftime会根据机器进行自动转换,更加可靠.

使用方法:

time_t start,end;
start = time(NULL); // or time(&start);
// calculations
end = time(NULL); // or time(&end);
printf("time = %f\n", difftime(end, start));

以下为示例程序:

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

void test1()
{
	time_t start, end;
	time(&start); // 或者 start = time(NULL);

	for (int i = 0; i < 10000; ++i)
	{
		int a = 100 * 100;
	}
	Sleep(2500);
	time(&end); // 或者 end = time(NULL);
	printf("time = %f\n", difftime(end, start)); // 注意difftime的返回值类型为double

	return;
}

int main(int argc, char* argv[])
{
	test1();
	system("pause");
	return 0;
}

由于此方法的计时精度并不高,只精确到秒,因此对于需要进行性能测试的场景,并不适合采用time()函数进行计时.

1.2 C++下的clock()函数

C++下使用clock()函数,可以实现毫秒级的计时(但不是特别精确).

该函数同样包含在time.h头文件中.

该函数返回的是clock_t类型的硬件滴答数,要换算成秒时,需要除以CLK_TCKCLOCKS_PER_SEC.

函数原型为 clock_t clock(void)

使用方法为:

cloct_t start, end;
start = clock();
// calculation
end = clock();
std::cout << "time = " << double(end-start) / CLK_TCK << "s" << std::endl;

以下为示例程序:

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

void test2()
{
	clock_t start, end;
	start = clock();
	for (int i = 0; i < 10000; ++i)
	{
		int a = 100 * 100;
	}
	Sleep(2500);
	end = clock();
	std::cout << "time = " << (double)(end - start) / CLK_TCK << "s" << std::endl;
}

int main(int argc, char* argv[])
{
	test2();
	system("pause");
	return 0;
}

2. windows.h下的方法

以下两种方法的头文件是一致的,都是windows.h,所以这两种方法可谓是WindowsAPI下常用的计时方法.

2.1 GetTickCount()

函数的原型:
DWORD WINAPI GetTickCount(void);

该函数返回设备启动后的毫秒数(但不精确),对于一般的实时控制可以采用该函数。

使用方法:

DWORD start, end;
start = GetTickCount();
// calculation;
end = GetTickCount();
std::cout << "time = " << (double)(end-start) << "ms" << std::endl;

代码举例:

#include <windows.h>
#include <iostream>

void test3()
{
	DWORD start, end;
	start = GetTickCount();
	for (int i = 0; i < 10000; ++i)
	{
		int a = 100 * 100;
	}
	Sleep(2500);
	end = GetTickCount();
	std::cout << "time = " << (double)(end - start) << "ms" << std::endl;
}

int main(int argc, char* argv[])
{
	test3();
	system("pause");
	return 0;
}

2.2 QueryPerformanceCounter()

QueryPerformanceCounter()QueryPerformanceFrequency()搭配使用,提供了windows环境下的高精度计时,前者获得的是CPU从开机以来执行的时钟周期数.后者用于获得机器一秒钟执行多少次,就是时钟周期.

该方法的精度误差一般不超过1 μ s \mu s μs,可以认为是透微秒级的高精度计时方法.

函数原型:

BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

使用方法:

LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
// calculation;
QueryPerformanceCounter(&t2);
std::cout << "time = " << (double)(t2.QuadPart - t1.QuadPart) / (double)tc.QuadPart * 1000 << "ms" << std::endl;

代码举例:

#include <windows.h>
#include <iostream>

void test4()
{
	LARGE_INTEGER t1, t2, tc;
	double time0;
	QueryPerformanceFrequency(&tc);
	QueryPerformanceCounter(&t1);
	Sleep(2500);
	QueryPerformanceCounter(&t2);
	std::cout << "time = " << (double)(t2.QuadPart - t1.QuadPart) / (double)tc.QuadPart * 1000 << "ms" << std::endl;
	
}

int main(int argc, char* argv[])
{
	test4();
	system("pause");
	return 0;
}

贴一下该代码的运行结果,看一下高精度计时器给出的计时结果
在这里插入图片描述

这个结果表明,其实Sleep函数的精度并不是很高.

3. C++11标准后的chrono库

chrono是C++11标准后的强大计时库.

本来打算写在这一篇的,发现内容有点多,可能需要单独开一篇来完成.

此处空缺一篇内容的链接,等写完以后补充在这里.

参考资料

  1. C语言中常用计时方法总结
  2. C++ 11 std::chrono库详解
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值