SunBo

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在程序设计过程中,往往要计算关键算法的程序执行时间,以考查时间复杂度。这是一个基础知识,但是可以以该主题为点,进行深入分析。本文就是要探讨这些方法的优缺点,以及适用环境。算是一个小的功能模块,为以后的程序设计提供支持。
2007-10-15
方法一:使用clock函数
NOTES
       The C standard allows for arbitrary values at the start of the program;
       subtract the value returned from a call to clock() at the start of the
       program to get maximum portability.

       Note that the time can wrap around. On a 32bit system where
       CLOCKS_PER_SEC equals 1000000 this function will return the same value
       approximately every 72 minutes.

       On several other implementations, the value returned by clock() also
       includes the times of any children whose status has been collected via
       wait() (or another wait-type call). Linux does not include the times
       of waited-for children in the value returned by clock(). The times()
       function, which explicitly returns (separate) information about the
       caller and its children, may be preferable.

    值得注意的是,使用clock函数作为计时器,最大为(2^32)us,也就是(2^32)/1000000s。换算成分钟的话,71.6minutes。由此看见,每隔大约72分钟,相当于归零一次,也就是wrap around。
    利用该机制测试的是测试部分运行占用的CPU的时间。还有一些细节因素需要注意。
模板如下:
#include
#include

int main(void)
{
        clock_t t_start;   /* start time when test starts */
        clock_t t_end;     /* end time when test ends */

        t_start = clock(); /* get start time */

        /* test code */

        t_end = clock();   /* get end time */

        /* display result */
        printf("time: %.3f s/n", (double)(t_end-t_start)/CLOCKS_PER_SEC);

        return 0;
}

方法二:使用gettimeofday函数
    方法一的精度还是比较小的,是毫秒级。如果要进行微秒级的计时,则可以使用gettimeofday。其基本的模型如同方法一。我建立了一个比较晚上的工程,主要的三个文件如下:
cal_time.h
[armlinux@lqm include]$ cat cal_time.h
/*
* Copyright 2007 (c), Shandong University
* All rights reserved.
*
* Filename : cal_time.h
* Description: header file about calculating executed time
* Author : Liu Qingmin
* Version : 1.0
* Date : 2007-10-15
*/

#ifndef CAL_TIME_H_
#define CAL_TIME_H_

#include /* gettimeofday needed */

/*
* self-definated data structure
* in order to calculate the time of all functions to be tested.
*/
typedef int (*p_func)();

/* to rely on implementation */
extern p_func p_func_array[];

/* module interface */
void cal_time(p_func p_func_array[], int size);

#endif /* CAL_TIME_H_ */

cal_time.c
[armlinux@lqm src]$ cat cal_time.c
/*
* Copyright 2007 (c), Shandong University
* All rights reserved.
*
* Filename : cal_time.c
* Description: calculate the time of program which carries out.
* Author : Liu Qingmin
* Version : 1.0
* Date : 2007-10-15
*/

#include
#include
#include

/*
* Function : cal_time
* Description: calculate the time of program which executes
* Parameters : p_func p_func_arr[] -- the function collection to be tested
* int size -- the number of functions to be tested
* Return : none
* Notice : you cannot calculate the number of element in array which is
* passed by value.
*/
void cal_time(p_func p_func_arr[], int size)
{
        struct timeval start, end;
        unsigned int sum = 0;
        int i;

        for (i=0; i                /* get start time */
                gettimeofday(&start, NULL);

                /* Test Code */
                p_func_arr[i]();

                /* get end time */
                gettimeofday(&end, NULL);

                sum += (1000000 * (end.tv_sec - start.tv_sec)
                        + (end.tv_usec - start.tv_usec));
        }

        /* print the result */
        printf("time: %.6f s./n", (double)sum / 1000000);
}

main.c

[armlinux@lqm src]$ cat main.c
/*
* Copyright 2007 (c), Shandong University
* All rights reserved.
*
* Filename : main.c
* Description:
* Author : Liu Qingmin
* Version : 1.0
* Date : 2007-10-15
*/

#include
#include

/* macro to calculate the number of array */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

/* test function */
int test1(void);
int test2(void);

p_func p_func_arr[] = {
        &test1,
        &test2
};

int main(void)
{
        cal_time(p_func_arr, ARRAY_SIZE(p_func_arr));

        return 0;
}

int test1(void)
{
        int i;

        for (i=0; i<(1<<4); i++) {
                printf("hello/n");
        }

        return 0;
}

int test2(void)
{
        int i;

        for (i=0; i<(1<<4); i++) {
                printf("world/n");
        }

        return 0;
}

这个机制适合测试大量函数。不过存在的问题也比较明显。这样测试的结果并不是非常准确,应该采用随机过程的处理方法,多测试几次然后取平均数。这样应该会更好一些。否则的话,测试的结果还是不具备科学的对比性。
    关于Linux下的各种时间的概念,还不是非常清晰,需要进一步的学习把握。

posted on 2010-07-23 11:00  SunBo  阅读(317)  评论(0编辑  收藏  举报