C++ 常用时间获取函数汇总
方法篇
法一: ros
#include
ros::Time begin = ros::Time::now();
... do some work ...
ros::Time end = ros::Time::now();
ros::Duration diff = begin - end;
double sec = diff.toSec();
std::cout << "Time used: " << sec << " s";
另外ros还有睡眠和指定频率循环的功能:
ros::Duration(0.5).sleep(); // sleep for half a second/// 以10Hz的频率执行以下循环
ros::Rate r(10); // 10 hz
while (ros::ok())
{... do some work ...r.sleep();
}
还可以使用 ros::Timer比 ros::Rate更灵活。具体参见:https://www.ncnynl.com/archives/201701/1284.html
法二: chrono
#include
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
... do some work ...
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << "Time used: " << diff.count() << " s";
法三: omp
基于OpenMP,没有类的封装,用起来更直观一些。(可能效率也更高点?)
#include
double start = omp_get_wtime(); //单位秒
... do some work ...
double end = omp_get_wtime(); //单位秒
double diff = end - start;
std::cout << "Time used: " << diff << " s";
法四: gettimeofday
#include using namespace std;// function with timer
double mysecond() {struct timeval tp;struct timezone tzp;int i;i = gettimeofday(&tp, &tzp);return ((double) tp.tv_sec + (double) tp.tv_usec * 1.e-6);
}void main(){double start = mysecond(); //单位秒... do some work ...double end = mysecond(); //单位秒double diff = end - start;std::cout << "Time used: " << diff << " s";
}
测试篇
测试最小时间间隔(重要!!!)
这里测试最小时间间隔(clock tick),应当是比较专业的测量了,最能代表方法的精度。后面的测试1、2都是在知道该方法前自己瞎测的。
//
// Created by daybeha on 2023/4/13.
//#include
#include
#include
#include
#include
#include using namespace std;#define N 50000template <typename T>
void compute_clock_granularity(T (*gettime)(), double (*getdiff)(T, T)){vector<T> ticks_vec(N);for (int i = 0; i < N; i++) {ticks_vec[i] = gettime();}double mindist = 1e10, maxdist = 0;for (int i = 1; i < N; i++) {double dist = getdiff(ticks_vec[i], ticks_vec[i - 1]);if (dist > 0) {if (dist < mindist) mindist = dist;if (dist > maxdist) maxdist = dist;}}cout.precision(2);cout << "min dist = " << mindist << " s, max dist = " << maxdist << " s, total time = " << getdiff(ticks_vec[N - 1], ticks_vec[0]) <<" s" << endl;
}double getdiff_double(double a, double b){return a - b;
}double getdiff_chrono(std::chrono::steady_clock::time_point a, std::chrono::steady_clock::time_point b){return std::chrono::duration<double>(a - b).count();
}double getdiff_ros(ros::Time a, ros::Time b){return (a - b).toSec();
}// function with timer
double mysecond() {struct timeval tp;struct timezone tzp;int i;i = gettimeofday(&tp, &tzp);return ((double) tp.tv_sec + (double) tp.tv_usec * 1.e-6);
}int main(int argc, char** argv){ros::init(argc,argv, "time_acquire");ros::NodeHandle n;// 法一cout << "ros:" << endl;compute_clock_granularity(ros::Time::now, getdiff_ros);// 法二cout << endl << "chrono:" << endl;compute_clock_granularity(std::chrono::steady_clock::now, getdiff_chrono);// 法三cout << endl << "OpenMP:" << endl;compute_clock_granularity<double>(mysecond, getdiff_double);// 法四cout << endl << "gettimeofday:" << endl;compute_clock_granularity<double>(mysecond,getdiff_double);
}
某次输出结果如下:

经过我的多次实验,ros和chrono的最小时间间隔一般最小,但ros的最大时间间隔一般最大, 其他三种方法的表现相差不大。
测试1
//
// Created by daybeha on 2022/6/27.
//#include
#include
#include
#include using namespace std;int main(int argc, char** argv){ros::init(argc,argv, "time_acquire");ros::NodeHandle n;ros::Rate r(50000);// 法一cout << "ros:" << endl;ros::Time begin_r = ros::Time::now();std::cout << "Start " << begin_r.toSec() << " s"<< endl;r.sleep();ros::Time end_r = ros::Time::now();std::cout << "End " << end_r.toSec() << " s"<< endl;ros::Duration diff_r = end_r - begin_r;double sec = diff_r.toSec();std::cout << "Time used: " << sec << " s" << endl;// 法二cout << endl << "chrono:" << endl;std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();std::cout << "Start " << start.time_since_epoch().count() << " s"<< endl;r.sleep();std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();std::cout << "End " << end.time_since_epoch().count() << " s"<< endl;std::chrono::duration<double> diff = end - start;std::cout << "Time used: " << diff.count() << " s"<< endl;// 法三cout << endl << "OpenMP:" << endl;double start_o = omp_get_wtime(); //单位秒std::cout << "Start " << start_o << " s"<< endl;r.sleep();double end_o = omp_get_wtime(); //单位秒std::cout << "End " << end_o << " s"<< endl;double diff_o = end_o - start_o;std::cout << "Time used: " << diff_o << " s"<< endl;
}
rate=100Hz

rate=1000Hz

rate=10000Hz

rate=50000Hz

rate=100000Hz

可以看到,随着频率增大,三种方法的时间都不怎么准了(当然r.sleep应该也不准了……),其中chrono最差。 ros整体耗时更高。
测试2
//
// Created by daybeha on 2022/6/27.
//#include
#include
#include
#include using namespace std;void test(){for (int i = 0; i < 10000; ++i) {for (int j = 0; j < 1000; ++j) {int a = i*j;}}
}int main(int argc, char** argv){ros::init(argc,argv, "time_acquire");ros::NodeHandle n;ros::Rate r(100000);// 法一cout << "ros:" << endl;ros::Time begin_r = ros::Time::now();std::cout << "Start " << begin_r.toSec() << " s"<< endl;
// r.sleep();test();ros::Time end_r = ros::Time::now();std::cout << "End " << end_r.toSec() << " s"<< endl;ros::Duration diff_r = end_r - begin_r;double sec = diff_r.toSec();std::cout << "Time used: " << sec << " s" << endl;// 法二cout << endl << "chrono:" << endl;std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();std::cout << "Start " << start.time_since_epoch().count() << " s"<< endl;
// r.sleep();test();std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();std::cout << "End " << end.time_since_epoch().count() << " s"<< endl;std::chrono::duration<double> diff = end - start;std::cout << "Time used: " << diff.count() << " s"<< endl;// 法三cout << endl << "OpenMP:" << endl;double start_o = omp_get_wtime(); //单位秒std::cout << "Start " << start_o << " s"<< endl;
// r.sleep();test();double end_o = omp_get_wtime(); //单位秒std::cout << "End " << end_o << " s"<< endl;double diff_o = end_o - start_o;std::cout << "Time used: " << diff_o << " s"<< endl;
}

结论: chrono获取时间的效率最高,OpenMP其次,ros最差!
python版可以参考另一篇文章:学习笔记 —— python代码耗时及内存占用测试方法 以及一些零碎的python小工具
Reference
C++ API文档
ROS与C++入门教程-Time(时间)
omp_get_wtime | Microsoft Docs
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
