重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
有4种方法可以达成测算程序运行时间的目的。
专注于为中小企业提供成都网站建设、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业林芝免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
它们分别是使用clock, times, gettimeofday, getrusage来实现的。
下面就来逐一介绍,并比较它们的优劣点。
系统测试环境:
VirtualBox (Ubuntu 9.10)
gcc version 4.4.1
libc6 2.10.1-0ubuntu16
Core Duo T2500 2GMHz
例程如下:
只要修改第11行的定义值,就可以使用不同的测量方法了。
#include sys/time.h
#include sys/resource.h
#include unistd.h
#include stdio.h
#include time.h
#define TEST_BY_CLOCK (char)(0x00)
#define TEST_BY_TIMES (char)(0x01)
#define TEST_BY_GETTIMEOFDAY (char)(0x02)
#define TEST_BY_GETRUSAGE (char)(0x03)
#define TEST_METHOD (TEST_BY_GETTIMEOFDAY)
#define COORDINATION_X (int)(1024)
#define COORDINATION_Y (int)(1024)
static int g_Matrix[COORDINATION_X][COORDINATION_Y];
double getTimeval()
{
struct rusage stRusage;
struct timeval stTimeval;
if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)
{
gettimeofday(stTimeval, NULL);
}
else if (TEST_METHOD == TEST_BY_GETRUSAGE)
{
getrusage(RUSAGE_SELF, stRusage);
stTimeval = stRusage.ru_utime;
}
return stTimeval.tv_sec + (double)stTimeval.tv_usec*1E-6;
}
int main()
{
int i, j;
int n = 0;
clock_t clockT1, clockT2;
double doubleT1, doubleT2;
if (TEST_METHOD == TEST_BY_CLOCK)
{
clockT1 = clock();
}
else if (TEST_METHOD == TEST_BY_TIMES)
{
times(clockT1);
}
else if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)
{
doubleT1 = getTimeval();
}
else if (TEST_METHOD == TEST_BY_GETRUSAGE)
{
doubleT1 = getTimeval();
}
for (i = 0; i COORDINATION_X; i++)
{
for (j = 0; j COORDINATION_Y; j++)
{
g_Matrix[i][j] = i * j;
}
}
if (TEST_METHOD == TEST_BY_CLOCK)
{
clockT2 = clock();
printf("Time result tested by clock = %10.30f\n",(double)(clockT2 - clockT1)/CLOCKS_PER_SEC);
}
else if (TEST_METHOD == TEST_BY_TIMES)
{
times(clockT2);
printf("Time result tested by times = %10.30f\n", (double)(clockT2 - clockT1)/sysconf(_SC_CLK_TCK));
}
else if (TEST_METHOD == TEST_BY_GETTIMEOFDAY)
{
doubleT2 = getTimeval();
printf("Time result tested by gettimeofday = %10.30f\n",(double)(doubleT2 - doubleT1));
}
else if (TEST_METHOD == TEST_BY_GETRUSAGE)
{
doubleT2 = getTimeval();
printf("Time result tested by getrusage = %10.70f\n", (double)(doubleT2 - doubleT1));
}
return 0;
}
1. 使用clock的方法:
clock是ANSI C的标准库函数,关于这个函数需要说明几点。
首先,它返回的是CPU耗费在本程序上的时间。也就是说,途中sleep的话,由于CPU资源被释放,那段时间将不被计算在内。
其次,得到的返回值其实就是耗费在本程序上的CPU时间片的数量,也就是Clock Tick的值。该值必须除以CLOCKS_PER_SEC这个宏值,才
能最后得到ss.mmnn格式的运行时间。在POSIX兼容系统中,CLOCKS_PER_SEC的值为1,000,000的,也就是
1MHz。
最后,使用这个函数能达到的精度大约为10ms。
2. 使用times的方法:
times的用法基本和clock类似,同样是取得CPU时间片的数量,所不同的是要除以的时间单位值为sysconf(_SC_CLK_TCK)。
3. 使用gettimeofday的方法:
用gettimeofday直接提取硬件时钟进行运算,得到的结果的精度相比前两种方法提高了很多。
但是也正由于它提取硬件时钟的原因,这个方法只能计算程序开始时间和结束时间的差值。而此时系统中如果在运行其他的后台程序,可能会影响到最终结果的值。如果后台繁忙,系统dispatch过多的话,并不能完全真实反映被测量函数的运行时间。
4. 使用getrusage的方法:
getrusage得到的是程序对系统资源的占用信息。只要指定了RUSAGE_SELF,就可以得到程序本身运行所占用的系统时间。
#include time.h
#include stdio.h
#include dos.h
int main(void)
{
time_t timer;
struct tm *tblock;
timer = time(NULL);
tblock = localtime(timer);
printf("Local time is: %s", asctime(tblock));
return 0;
}
tm结构定义如下:
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
c语言时间函数:
1、获得日历时间函数:
可以通过time()函数来获得日历时间(Calendar Time),其原型为:time_t time(time_t * timer);
如果已经声明了参数timer,可以从参数timer返回现在的日历时间,同时也可以通过返回值返回现在的日历时间,即从一个时间点(例如:1970年1月1日0时0分0秒)到现在此时的秒数。如果参数为空(NUL),函数将只通过返回值返回现在的日历时间,比如下面这个例子用来显示当前的日历时间:
2、获得日期和时间函数:
这里说的日期和时间就是平时所说的年、月、日、时、分、秒等信息。从第2节我们已经知道这些信息都保存在一个名为tm的结构体中,那么如何将一个日历时间保存为一个tm结构的对象呢?
其中可以使用的函数是gmtime()和localtime(),这两个函数的原型为:
struct tm * gmtime(const time_t *timer);
struct tm * localtime(const time_t * timer);
其中gmtime()函数是将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间,而localtime()函数是将日历时间转化为本地时间。比如现在用gmtime()函数获得的世界标准时间是2005年7月30日7点18分20秒,那么用localtime()函数在中国地区获得的本地时间会比世界标准时间晚8个小时,即2005年7月30日15点18分20秒。
有,CLOCK函数。
clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t。在MSDN中,查得对clock函数定义如下:clock_t clock(void) ; #ifndef _CLOCK_T_DEFINED typedef long clock_t;
#define _CLOCK_T_DEFINED #endif。
可以看到每过千分之一秒(1毫秒),调用clock函数返回的值就加1。
C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器以及超级电脑等作业平台。
1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是产生了BCPL语言。
1、C语言中读取系统时间的函数为time(),其函数原型为:\x0d\x0a#include \x0d\x0atime_t time( time_t * ) ;\x0d\x0atime_t就是long,函数返回从1970年1月1日(MFC是1899年12月31日)0时0分0秒,到现在的的秒数。\x0d\x0a2、C语言还提供了将秒数转换成相应的时间格式的函数:\x0d\x0a char * ctime(const time_t *timer); //将日历时间转换成本地时间,返回转换后的字符串指针 可定义字符串或是字符指针来接收返回值\x0d\x0a struct tm * gmtime(const time_t *timer); //将日历时间转化为世界标准时间(即格林尼治时间),返回结构体指针 可定义struct tm *变量来接收结果\x0d\x0a struct tm * localtime(const time_t * timer); //将日历时间转化为本地时间,返回结构体指针 可定义struct tm *变量来接收结果\x0d\x0a3、例程:\x0d\x0a#include \x0d\x0avoid main()\x0d\x0a{\x0d\x0a time_t t;\x0d\x0a struct tm *pt ;\x0d\x0a char *pc ;\x0d\x0a time(t);\x0d\x0a pc=ctime(t) ; printf("ctime:%s", pc );\x0d\x0a pt=localtime(t) ; printf("year=%d", pt-tm_year+1900 );\x0d\x0a}\x0d\x0a\x0d\x0a时间结构体struct tm 说明:\x0d\x0a\x0d\x0astruct tm { \x0d\x0a int tm_sec; /* 秒 _ 取值区间为[0,59] */ \x0d\x0a int tm_min; /* 分 - 取值区间为[0,59] */ \x0d\x0a int tm_hour; /* 时 - 取值区间为[0,23] */ \x0d\x0a int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */ \x0d\x0a int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */ \x0d\x0a int tm_year; /* 年份,其值等于实际年份减去1900 */ \x0d\x0a int tm_wday; /* 星期 _ 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */ \x0d\x0a int tm_yday; /* 从每年的1月1日开始的天数 _ 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */ \x0d\x0a int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/ \x0d\x0a};
#include cstdio
#include ctime
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void printTime() {
struct tm t; //tm结构指针
time_t now; //声明time_t类型变量
time(now); //获取系统日期和时间
localtime_s(t, now); //获取当地日期和时间
//格式化输出本地时间
printf("年-月-日-时-分-秒:%d-%d-%d %d:%d:%d\n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
int main(int argc, char** argv) {
printTime();
}