您的位置:首页 > 编程语言 > C语言/C++

C++:模拟实现类似<time.h>的计时功能

2016-04-16 17:31 519 查看

C++:模拟实现类似
<time.h>
的计时功能

标签: 计时 time.h

by 小威威

既然要模拟
<time.h>
中的计时功能,我们首先当然要先了解
<time.h>
这个头文件—–>C/C++ time.h 的用法

我们知道,一般情况下,我们是通过调用
<time.h>
中的clock()函数以及利用CLOCKS_PER_SEC参数实现一个事件或者是代码运行的计时。那么,我们能不能自己写一个头文件来实现对一个事件的计时呢?

显然这是可以的,那就是通过变量增长实现事件计时,这也是
<time.h>
中这一计时功能的设计核心。

我们先定义一个全局变量_clock代表当前代码运行时刻(注意区分时间与时刻)。

static int _clock = 0;


然后我们将代码运行的初始时刻定义为0(此时_clock在数值上就等于代码运行的时间,但是我们最好还是将它当作一个时刻)

接着设置一个clock_f()函数来实现_clock的增加。增加的量是执行一次函数所需要的时间。注意:这个时间的单位是block。block代表的是系统的计时单元。

然后不难想到需要两个标识点—start 和 finish 来记录事件的开始时刻与结束时刻。将这二者相减就是一个事件的运行时间,不过这个时间是以系统时间单元为单位的。因此,为了将其用我们一般的时间单位表示出来,还需要进行单位的换算。

此处就需要_CLOCKS_PER_SEC参数来实现转化了。这个参数代表每ms所代表的时间单元数。将以系统时间单元为单位的时间除以该参数就能将单位化成ms了。

还有一点需要注意的是:精度问题。单位换算不要忘记在乘上1.0以确保double精度。

这里再补充一下cout的格式化输出。

如若要保留小数点后三位有效数字,那么:

注意定义命名空间谷歌风格的问题:

记得在花括号的后面补上注释: // namespace XXX

XXX代表命名空间的名称

double a = 1.2323232;
cout << std::setiosflags(std::iOS::fixed) << std::setprecision(3) << a << endl;


下面呈现一道例题:

Carson write a simple program to solve Fabonaci and Factorial.
But he wants to know how it cost time when different inputs are given.
Now you are invited as an best expert to fix it.
Read main.cpp for details about the functions of 'timer.h'.

clock_f // the system provides a piece of time
>>>>>> TIC_TOC(namespace) <<<<<<
------ timer(class_1) ------
tic_f // start timing
toc_f // end timing
tictoc // print all the cost-time information(3 digits after the decimal point)
*Format:
line 0 - 1: 0.050ms
------ timer_controller(class_2) ------
# Used for storing timers
create // create timer
display // print the total-cost-time of all the timers(3 digits after the decimal point)
*format:
#Timer_1: 0.950ms
#Timer_2: 2.000ms

Something you need to know:
class 'timer' and 'timer_controller' is needed;
every clock_f() takes 50 clocks;
every millisecond takes 1000 clocks;
there are less than 10000 lines and 5 timers;

standard input
1 2 3 4 5
6 7 8 9 10

standard output
input: 1, result: 1
input: 2, result: 2
input: 3, result: 2
input: 4, result: 4
input: 5, result: 5
line 0 - 1: 0.050ms
line 1 - 2: 0.050ms
line 2 - 3: 0.150ms
line 3 - 4: 0.250ms
line 4 - 5: 0.450ms
input: 6, result: 720
input: 7, result: 5040
input: 8, result: 40320
input: 9, result: 362880
input: 10, result: 3628800
line 0 - 1: 0.300ms
line 1 - 2: 0.350ms
line 2 - 3: 0.400ms
line 3 - 4: 0.450ms
line 4 - 5: 0.500ms
#Timer_1: 0.950ms
#Timer_2: 2.000ms


实现代码如下:

// main.cpp
#include <iostream>
#include "timer.h"
using std::cin;
using std::cout;
using std::endl;
using std::string;
using namespace TIC_TOC;

// f(n) = 0, n = 1
// f(n) = 1, n = 2
// f(n) = f(n-1) + f(n-2), n > 2
int fabonaci(int n) {
clock_f();  // it takes 50 clocks (0.050ms)
if (n == 1) return 0;
else if (n == 2) return 1;
else return fabonaci(n-1) + fabonaci(n-2);
}

// f(n) = 1, n = 1
// f(n) = n * f(n-1), n > 1
int factorial(int n) {
clock_f();
if (n == 1) return 1;
return n*factorial(n-1);
}

timer_controller T;  // create a timer_controller
int number[5];  // input for test
int count;  // count the lines(tic -> toc)

void testTicToc(int n, string function) {
count = 0;
cin >> number[0] >> number[1] >> number[2]
>> number[3] >> number[4];
for (int i = 0; i < 5; i++) {
T
.tic_f(count++);  // tic for starting time
cout << "input: " << number[i] << ", result: ";
if (function == "fabonaci")
cout << fabonaci(number[i]) << endl;
else if (function == "factorial")
cout << factorial(number[i]) << endl;
T
.toc_f(count);  // toc for ending time
}
T
.tictoc(stdout);  // print out the line-time information
}

int main(void) {
T.create(2);
testTicToc(0, "fabonaci");
testTicToc(1, "factorial");
T.display(stdout);  // print out the total time of each timer
return 0;
}

//timer.h
# include <iostream>
# include <cstdio>
# include <iomanip>
# define MAX_TIMER 5
# define N 6

using std::cout;
using std::endl;
using std::ios;

static int _clock = 0;
inline void clock_f() { _clock += 50; }
inline double getTime() { return _clock / (1000*1.0); }

namespace TIC_TOC {
class timer {
private:
double clocks
;
public:
timer() {}
double getAllRdtsc() { return clocks[5] - clocks[0]; }
void tic_f(int count) { clocks[count] = getTime(); }
void toc_f(int count) { clocks[count] = getTime(); }
void tictoc(FILE* out) {
/*for (int i = 0; i < N-1; i++) {
cout << std::setiosflags(ios::fixed) << std::setprecision(3)
<< "line " << i << " - " << i+1 << ": "
<< clocks[i+1] - clocks[i] << "ms" << endl;;
}*/
for (int i = 0; i < N-1; i++) {
fprintf(out, "line %d - %d: %.3lfms\n", i, i+1,
clocks[i+1]-clocks[i]);
}
fflush(out);
}
};
class timer_controller {
private:
timer timePiece[MAX_TIMER];
int size;
public:
timer_controller() : size(0) {}
void create(int size) { this->size = size; }
timer& operator[](const int& val) { return timePiece[val]; }
void display(FILE* out) {
for (int i = 0; i < size; i++) {
/*cout << "#Timer_" << i+1 << ": "
<< (*this)[i].getAllRdtsc() << "ms" << endl;*/
fprintf(out, "#Timer_%d: %.3lfms\n", i+1,
((*this)[i].getAllRdtsc()));
}
fflush(out);
}
};
}  // namespace TIC_TOC


虽然这个小代码相对于
<time.h>
有不少缺陷,但是通过这种模拟我们更加清楚的了解了
<time.h>
中计数功能的实现原理。总体来说,还是会有收获的~

以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: