引言
我们在写算法时要考虑到算法的执行效率,有的题目规定了时间限制,我们需要在这个时间之内去解决问题。如果我们需要比对算法的好坏,就需要输出这个程序运行了多长时间。
在C或C++中计算程序执行时间,可以使用多种方法,下面我介绍几种比较常见且好用的几种方法,大家可以选择适合自己的一种记住就可以了。
方法1:使用 clock()
函数(C/C++)
在C/C++中,<time.h>
库提供了clock()
函数。这个方法是博主比较推荐的一个,非常简便,且易懂,它用于测量程序的CPU时间。clock()
函数返回程序从启动到函数被调用时所经过的时钟周期数。这个函数主要用于测量程序的CPU时间消耗,而不是实际的墙钟时间(即从墙上的时钟测量的时间)。
函数原型
clock_t clock(void);
clock_t
类型,表示自程序启动以来的时钟周期数。
使用实例:
以下是使用clock()
函数计算递归与非递归程序执行时间的示例代码:
#include<iostream>
#include<time.h>
using namespace std;
typedef long long ll;ll n, sum=1;ll fun(int dep) {//递归函数if (dep == 1) {return 1;}else {return 2 * (fun(dep - 1) + 1);}
}
void test0() {//非递归直接利用数学公式推理cin >> n;for (int i = 0; i < n-1; i++) {sum = (sum + 1) * 2;}cout << sum << endl;//printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC);
}
void test01() {cin >> n;cout << fun(n) << endl;//printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC);
}
int main() {// 开始时间clock_t start = clock();// 要执行的代码// ...test01();// 结束时间clock_t end = clock();// 计算执行时间(以秒为单位)double execution_time = (double)(end - start) / CLOCKS_PER_SEC;// 输出执行时间printf("程序执行时间:%f 秒\n", execution_time);return 0;
}
第一个是 递归的程序占用CPU的时间,第二个是非递归的程序占用CPU的时间。
注意事项
CLOCKS_PER_SEC
是<time.h>
库中定义的一个宏,表示每秒的时钟周期数。- (end - start) 单位是毫秒, 除以CLOCKS_PER_SEC周期转化为以秒为单位。
clock()
函数返回的是程序占用CPU的时间 ≠ 程序的实际运行时间。clock()
函数返回的是程序占用CPU的时间,不包括睡眠时间或其他非CPU时间。- 在多处理器系统上,
clock()
函数的行为可能有所不同,具体取决于操作系统的实现。 clock()
函数的精度依赖于系统,可能每次运行程序可能不相同。
clock()
函数是测量程序性能的一个简单工具,但它不适用于需要高精度时间测量的场景,适用于对比算法时,不需要计算准确时间。对于更高精度的时间测量,可以考虑使用C++11中的 <chrono>
库,或者在Unix-like系统中使用 clock_gettime()
函数。
方法2:使用 <chrono>
库(C++11及以上)
C++11引入了<chrono>
库,它提供了高精度的时间测量功能。这个库里面有很多函数,都是与时间有关的,功能非常强大,下面列举一个比较常用的函数。
函数实例:
std::chrono::system_clock::now | 获取当前系统时间的时间点 |
std::chrono::steady_clock::now | 获取当前稳定时间的时间点 |
std::chrono::high_resolution_clock::now | 获取当前高分辨率时间的时间点 |
std::chrono::time_point | 模板类,用于表示时间点 |
std::chrono::duration | 模板类,用于表示时间间隔 |
std::chrono::system_clock::to_time_t | 将time_point 转换为std::time_t |
std::chrono::system_clock::from_time_t | 将std::time_t 转换为time_point |
std::put_time | 用于将时间格式化为字符串 |
std::this_thread::sleep_for | 使当前线程睡眠一段时间 |
这个是实打实的计算程执行时间的,其原理类似一个计时器,当执行到 auto start = std::chrono::high_resolution_clock::now();这个语句获取一个时间,开始计时。auto end = std::chrono::high_resolution_clock::now();这个语句也是获取一个时间,执行完就结束计时,最后,使用count()
函数以秒为单位打印出运行时间。
代码示例:
以下是使用<chrono>
库计算程序执行时间的示例代码:
#include <iostream>
#include <chrono>using namespace std;int main() {// 开始时间点auto start = chrono::high_resolution_clock::now();// 要执行的代码// ...// 结束时间点auto end = chrono::high_resolution_clock::now();// 计算持续时间chrono::duration<double, milli> duration = end - start;// 输出执行时间cout << "程序执行时间:" << duration.count() << "毫秒" << endl;return 0;
}
方法3:使用time.h头文件中的time()函数
time.h
是 C 语言标准库中的一个头文件,它提供了多种与时间相关的函数。这个time函数是C语言初学者最熟悉的一个。其中,time()
函数用于获取当前的日历时间(自1970年1月1日00:00:00 UTC以来的秒数)。
time.h头文件常用函数:
-
time():
- 功能:获取当前时间。
- 原型:
time_t time(time_t *tloc);
- 返回值:返回当前时间(自1970年1月1日00:00:00 UTC以来的秒数),如果出错返回-1。
- 参数:
tloc
是一个可选的指针,如果提供,函数会将当前时间存储在这个指针指向的位置。
-
ctime():
- 功能:将 time_t 值转换为本地时间的字符串表示。
- 原型:
char *ctime(const time_t *timep);
- 返回值:返回一个指向以 null 结尾的字符串的指针,该字符串表示本地时间。
-
localtime():
- 功能:将 time_t 值转换为表示本地时间的 tm 结构体。
- 原型:
struct tm *localtime(const time_t *timep);
- 返回值:返回一个指向 tm 结构体的指针,该结构体包含本地时间。
-
gmtime():
- 功能:将 time_t 值转换为表示 UTC 时间的 tm 结构体。
- 原型:
struct tm *gmtime(const time_t *timep);
- 返回值:返回一个指向 tm 结构体的指针,该结构体包含 UTC 时间。
-
difftime():
- 功能:计算两个 time_t 值之间的差异(以秒为单位)。
- 原型:
double difftime(time_t time1, time_t time2);
- 返回值:返回两个时间之间的差异。
-
mktime():
- 功能:将 tm 结构体转换为 time_t 值。
- 原型:
time_t mktime(struct tm *timeptr);
- 返回值:返回表示时间的时间戳。
-
asctime():
- 功能:将 tm 结构体转换为 24 小时制的时间字符串。
- 原型:
char *asctime(const struct tm *timeptr);
- 返回值:返回一个指向以 null 结尾的字符串的指针,该字符串表示时间。
-
strftime():
- 功能:根据指定的格式将 time_t 或 tm 结构体的时间格式化为字符串。
- 原型:
size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr);
- 返回值:返回写入的字符数。
代码示例:
以下是如何使用 time.h
头文件中的 time()
函数来计算递归与非递归程序的一个简单示例:
#include<iostream>
#include<time.h>using namespace std;
typedef long long ll;ll n, sum=1;ll fun(int dep) {//递归函数if (dep == 1) {return 1;}else {return 2 * (fun(dep - 1) + 1);}
}
void test0() {//非递归直接利用数学公式推理cin >> n;for (int i = 0; i < n-1; i++) {sum = (sum + 1) * 2;}cout << sum << endl;
}
void test01() {cin >> n;cout << fun(n) << endl;
}int main(){time_t start=time(NULL);//开始时间test01();//这里填写您测试的代码time_t end =time(NULL);//结束时间double dif_time=difftime(end, start);//计算差值cout<<dif_time<<endl;return 0;
}
对于这种计算算法的执行效率肯定是不会考的,可能在测试以及开发过程中使用,大家看看图一乐就行,对于日期问题的考察可以看一下这一篇文章:【算法】日期问题(C/C++)-CSDN博客
执笔至此,感触彼多,全文将至,落笔为终,感谢大家的支持。