std chrono 测试例子

话不多说,直接上代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <thread>

//本文只探讨C++11中的功能,C++20该库进行了升级
//官方网址https://en.cppreference.com/w/cpp/chrono
//有一篇博客讲的也很好https://blog.csdn.net/albertsh/article/details/105468687

int main()
{
	//最开始,列出程序中最常用的,一个程序片段使用时间的计算(建议直接用第一种duration_cast + steady_clock):
	{
		//1、duration_cast + steady_clock
		auto timePoint_start_1 = std::chrono::steady_clock::now();
		std::this_thread::sleep_for(std::chrono::milliseconds(100));//do somethings
		auto timePoint_end_1 = std::chrono::steady_clock::now();
		auto takeTime_1 = std::chrono::duration_cast<std::chrono::milliseconds>(timePoint_end_1 - timePoint_start_1).count();
		printf("takeTime_1: %lldms\n", takeTime_1);//%lld打印long long
		std::cout << "takeTime_1: " << takeTime_1 << "ms" << std::endl;
		printf("\n");
		//
		//
		//
		//2、time_point_cast + steady_clock
		using ms_time_point = std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds>;
		auto timePoint_start_2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
		std::this_thread::sleep_for(std::chrono::milliseconds(100));//do somethings
		auto timePoint_end_2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now());
		auto takeTime_2 = (timePoint_end_2 - timePoint_start_2).count();
		printf("takeTime_2: %lldms\n", takeTime_2);//%lld打印long long
		std::cout << "takeTime_2: " << takeTime_2 << "ms" << std::endl;
		printf("\n");
	}


	//std::chrono主要由三部分组成,分别是durations、clocks、time_point

	{
		/*
			1、std::chrono::duration(持续时间),duration是类模板,它有两个参数:std::chrono::duration<数值类型, 时间单位>
			第一个参数_Rep是一个数值类型,通常是内置数值类型,后面构造对象时数值是多少就表示有多少个时间单位,这样就构成了一个时间长度(持续时间);
			第二个参数_Period是std::ratio模板类的一个实例,代表一个时间单位。_Period缺省值为std::ratio<1>,此时它的单位为秒。
		*/
		{
			/*
				0、std::ratio(比例)
				定义在<ratio>文件中,提供了编译期的比例计算功能,为std::chrono::duration提供基础服务。
				标准库预定义了一些常用比例,见https://en.cppreference.com/w/cpp/numeric/ratio/ratio
			*/
			{
				std::ratio<3, 1> raito_3_1;
				std::ratio<1, 3> raito_1_3;
				using ratio_1_10 = std::deci;
				using ratio_1_1000 = std::milli;
				using ratio_1_1000000 = std::micro;
				using ratio_10_1 = std::deca;
				using ratio_1000_1 = std::kilo;
				using ratio_1000000_1 = std::mega;
			}


			/*
				chrono中已经定义了nanoseconds、microseconds、milliseconds、seconds、minutes、hours这些常用的类
				可以通过这些类构造一些比较常用的对象以供使用
			*/
			{
				//chrono中的持续时间类和对象构造使用
				auto _24_hours = std::chrono::hours{ 24 };//传参24给类std::chrono::hours,构造出一个对象_24_hours,下面含义相同
				auto _60_minutes = std::chrono::minutes(60);
				auto _2_seconds = std::chrono::seconds(2);
				auto _100_milliseconds = std::chrono::milliseconds(100);
				auto _100000_microseconds = std::chrono::microseconds(100000);
				auto _1_nanoseconds = std::chrono::nanoseconds(1);
				std::this_thread::sleep_for(_2_seconds);
				std::this_thread::sleep_for(std::chrono::seconds(1));
				std::this_thread::sleep_for(std::chrono::milliseconds(100));
				printf("\n");
				auto _1_2_seconds_format1 = std::chrono::milliseconds(500);
				//auto _1_2_seconds_format2 = std::chrono::seconds(0.5);//这句话不被允许,因为std::chrono::seconds第一个参数为long long
				printf("\n");
				std::chrono::seconds duration1;//假设构造duration对象时不给数值参数,则会以一个负数初始化
				std::cout << "cnt: " << duration1.count() << std::endl;
				std::cout << "min: " << duration1.min().count() << std::endl;
				duration1 = std::chrono::seconds(10001);
				std::cout << "cnt: " << duration1.count() << std::endl;
				printf("hello1\n");
			}


			/*
				std::chrono::duration类对象的count、max、min方法
				count表示当前对象拥有的时间单位的数量,而时间长度=时间单位*数量
				max表示当前对象最多能够拥有的时间单位的数量,min表示当前对象最少能够拥有的时间单位的数量
			*/
			{
				auto _1_seconds = std::chrono::seconds(1);
				auto cnt1 = _1_seconds.count();
				auto min1 = _1_seconds.min();
				auto max1 = _1_seconds.max();
				std::cout << "cnt1: " << cnt1 << std::endl;
				std::cout << "min1: " << min1.count() << std::endl;
				std::cout << "max1: " << max1.count() << std::endl;
				printf("\n");
				auto _2_seconds = std::chrono::seconds(2);
				auto cnt2 = _2_seconds.count();
				auto min2 = _2_seconds.min();
				auto max2 = _2_seconds.max();
				std::cout << "cnt2: " << cnt2 << std::endl;
				std::cout << "min2: " << min2.count() << std::endl;
				std::cout << "max2: " << max2.count() << std::endl;
				printf("\n");
				auto _1_minutes = std::chrono::minutes(1);
				auto cnt3 = _1_minutes.count();
				auto min3 = _1_minutes.min();
				auto max3 = _1_minutes.max();
				std::cout << "cnt3: " << cnt3 << std::endl;
				std::cout << "min3: " << min3.count() << std::endl;
				std::cout << "max3: " << max3.count() << std::endl;
				printf("\n");
				auto _60_minutes = std::chrono::minutes(60);
				auto cnt4 = _60_minutes.count();
				auto min4 = _60_minutes.min();
				auto max4 = _60_minutes.max();
				std::cout << "cnt4: " << cnt4 << std::endl;
				std::cout << "min4: " << min4.count() << std::endl;
				std::cout << "max4: " << max4.count() << std::endl;
				printf("\n");
			}


			/*
				自定义持续时间类,构造对象和使用
			*/
			{
				/
				//自定义持续时间类
				using _int_one_second = std::chrono::duration<int>;//std::chrono::duration第二个参数缺省值为std::ratio<1>
				using _short_one_second = std::chrono::duration<short>;
				using _double_one_second = std::chrono::duration<double>;
				using _longlong_one_second = std::chrono::duration<long long>;//std::chrono::seconds就是这个
				using _int_two_second = std::chrono::duration<int, std::ratio<2, 1>>;
				using _float_half_second = std::chrono::duration<float, std::ratio<1, 2>>;
				using _double_1_3_second = std::chrono::duration<double, std::ratio<1, 3>>;
				/
				//构造对象
				_int_one_second duration1;//假设构造duration对象时不给数值参数,则会以一个负数初始化
				std::cout << "cnt: " << duration1.count() << std::endl;
				std::cout << "min: " << duration1.min().count() << std::endl;
				duration1 = _int_one_second(1);
				std::cout << "cnt: " << duration1.count() << std::endl;
				printf("hello1\n");
				//auto _1_2_seconds_format1 = _int_one_second(0.5);//这句话不被允许,因为_int_one_second类第一个参数应该为int
				auto _1_2_seconds_format2 = _double_one_second(0.5);
				auto _2_2_second = _float_half_second(2.0f);
				auto _2_3_second = _double_1_3_second(2.0);
				/
				//使用
				std::this_thread::sleep_for(_double_one_second(0.5));
				std::this_thread::sleep_for(_1_2_seconds_format2);
				std::this_thread::sleep_for(_float_half_second(4.0f));
				std::this_thread::sleep_for(_short_one_second(1));
				printf("hello2\n");
				printf("\n");
			}


			/*
				持续时间作和、差、比较
			*/
			{
				{
					//普通的和、差
					auto _1_seconds = std::chrono::seconds(1);
					auto _2_seconds = std::chrono::seconds(2);
					auto duration1_1 = _1_seconds + _2_seconds;
					auto duration1_2 = _1_seconds - _2_seconds;
					std::cout << "duration1_1: " << duration1_1.count() << std::endl;
					std::cout << "duration1_1 type is: " << typeid(duration1_1).name() << std::endl;
					std::cout << "duration1_2: " << duration1_2.count() << std::endl;
					std::cout << "duration1_1 type is: " << typeid(duration1_2).name() << std::endl;
					auto _1_milliseconds = std::chrono::milliseconds(1);
					auto duration2_1 = _1_seconds + _1_milliseconds;
					auto duration2_2 = _1_seconds - _1_milliseconds;
					std::cout << "duration2_1: " << duration2_1.count() << std::endl;
					std::cout << "duration2_1 type is: " << typeid(duration2_1).name() << std::endl;
					std::cout << "duration2_2: " << duration2_2.count() << std::endl;
					std::cout << "duration2_2 type is: " << typeid(duration2_2).name() << std::endl;
					printf("\n");
				}
				/
				{
					//对于两个不同的std::ratio类型相加(减),最终得到的std::ratio类型为两个std::ratio分子取最大公约数,分母取最小公倍数
					auto duration1_1 = std::chrono::duration<double, std::ratio<9, 7>>(3);
					auto duration1_2 = std::chrono::duration<double, std::ratio<6, 5>>(1);
					auto duration1_3 = duration1_1 + duration1_2;
					auto duration1_4 = duration1_1 - duration1_2;
					std::cout << "duration1_3: " << duration1_3.count() << std::endl;
					std::cout << "duration1_3 type is: " << typeid(duration1_3).name() << std::endl;
					std::cout << "duration1_4: " << duration1_4.count() << std::endl;
					std::cout << "duration1_4 type is: " << typeid(duration1_4).name() << std::endl;
					printf("\n");
				}
				/
				{
					//比较
					auto _1_seconds = std::chrono::seconds(1);
					auto _2_seconds = std::chrono::seconds(2);
					auto _double_1_3_seconds = std::chrono::duration<double, std::ratio<1, 3>>(1);
					if (_1_seconds * 2 == _2_seconds)
						printf("_1_seconds * 2 == _2_seconds\n");//显然成立
					if (_double_1_3_seconds * 3 == _1_seconds)
						printf("_double_1_3_seconds * 2 == _1_seconds\n");//如果不相等,可能的原因是浮点数的关系
					if ((_double_1_3_seconds * 3 - _1_seconds).count() < 1e-4)
						printf("(_double_1_3_seconds * 2 - _1_seconds).count() < 1e-4\n");//这样就满足啦
					printf("\n");
				}
			}


			/*
				持续时间的单位转换std::chrono::duration_cast
			*/
			{
				auto _1_seconds = std::chrono::seconds(1);
				auto duration1 = std::chrono::duration_cast<std::chrono::minutes>(_1_seconds);//秒转为分钟为单位
				std::cout << "duration1: " << duration1.count() << std::endl;//这里得到的是0
				auto duration2 = std::chrono::duration_cast<std::chrono::duration<double, std::ratio<60>>>(_1_seconds);//因此我们自定义一个double类型的分钟
				std::cout << "duration2: " << duration2.count() << std::endl;//这里得到的是小数
				auto duration3 = std::chrono::duration_cast<std::chrono::milliseconds>(_1_seconds);//秒转为毫秒为单位
				std::cout << "duration3: " << duration3.count() << std::endl;
				printf("\n");
			}
		}
	}

	
	printf("\n");
	{
		/*
			2、clocks(时钟),主要包括system_clock、steady_clock、high_resolution_clock
			system_clock表示系统时钟,代表真实世界的时间,具体值依赖于系统;(如果两次调用now()方法之间,系统时间被修改了,那么两次的差值就很难说了)
			steady_clock不能被“调整”的时钟,不一定是世界时钟,但通过其now()方法得到的时间值不会是递减的;(系统时间修改不会影响它)
			high_resolution_clock,实际上是system_clock或者steady_clock的别名而已,具体是谁根据系统而定
		*/
		{
			//查看system_clock和steady_clock的成员和成员函数
			{
				/*
					std::chrono::system_clock的成员和成员函数,system_clock比steady_clock多两个成员函数to_time_t、from_time_t
				*/
				auto time_point1 = std::chrono::system_clock::now();//这里得到一个time_point
				//std::cout << "time_point1: " << time_point1 << std::endl;//time_point不能被打印
				std::cout << "system_clock::is_steady is: " << std::chrono::system_clock::is_steady << std::endl;
				std::cout << "system_clock::period type is: " << typeid(std::chrono::system_clock::period).name() << std::endl;
				std::cout << "system_clock::rep type is: " << typeid(std::chrono::system_clock::rep).name() << std::endl;
				std::cout << "system_clock::duration type is: " << typeid(std::chrono::system_clock::duration).name() << std::endl;
				std::cout << "system_clock::time_point type is: " << typeid(std::chrono::system_clock::time_point).name() << std::endl;
				auto ctime1 = std::chrono::system_clock::to_time_t(time_point1);//将一个time_point转换成ctime
				auto time_point2 = std::chrono::system_clock::from_time_t(ctime1);//将一个ctime转换成time_point
				printf("\n");
			}


			{
				/*
					std::chrono::steady_clock的成员和成员函数
				*/
				auto time_point2 = std::chrono::steady_clock::now();//这里得到一个time_point
				//std::cout << "time_point2: " << time_point2 << std::endl;//time_point不能被打印
				std::cout << "steady_clock::is_steady is: " << std::chrono::steady_clock::is_steady << std::endl;
				std::cout << "steady_clock::period type is: " << typeid(std::chrono::steady_clock::period).name() << std::endl;
				std::cout << "steady_clock::rep type is: " << typeid(std::chrono::steady_clock::rep).name() << std::endl;
				std::cout << "steady_clock::duration type is: " << typeid(std::chrono::steady_clock::duration).name() << std::endl;
				std::cout << "steady_clock::time_point type is: " << typeid(std::chrono::steady_clock::time_point).name() << std::endl;
				printf("\n");
			}
		}


		{
			/*
				计算两个时间点的时间间隔,通常用于计算一个步骤所花费的时间,通常system_clock和steady_clock都能够胜任,
				只用来计算时间间隔的话,理论上steady_clock更好一些
			*/
			auto time1 = std::chrono::system_clock::now();//这里得到一个time_point
			std::this_thread::sleep_for(std::chrono::milliseconds(100));
			auto time2 = std::chrono::system_clock::now();
			auto takeTime1 = (time2 - time1).count();
			auto takeTime2 = std::chrono::duration_cast<std::chrono::milliseconds>(time2 - time1).count();
			std::cout << "takeTime1: " << takeTime1 << std::endl;
			std::cout << "takeTime2: " << takeTime2 << std::endl;
			printf("\n");
			auto time3 = std::chrono::steady_clock::now();//这里得到一个time_point
			std::this_thread::sleep_for(std::chrono::milliseconds(100));
			auto time4 = std::chrono::steady_clock::now();
			auto takeTime3 = std::chrono::duration_cast<std::chrono::milliseconds>(time4 - time3).count();
			std::cout << "takeTime3: " << takeTime3 << std::endl;
			printf("\n");
		}

		{
			/*
				std::chrono::system_clock::to_time_t	方法将一个time_point转换成ctime
				std::chrono::system_clock::from_time_t	方法将一个ctime转换成time_point
				结合<iomanip>中的std::put_time和<ctime>中的std::localtime可以将时间格式化输出
				注意GCC对<iomanip>中std::put_time的支持未知
			*/
			auto ctime1 = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
			auto time_point1 = std::chrono::system_clock::from_time_t(ctime1);
			//时间格式化输出
			std::cout << std::put_time(std::localtime(&ctime1), "%Y-%m-%d %X") << std::endl;
			std::cout << std::put_time(std::localtime(&ctime1), "%Y-%m-%d %H.%M.%S") << std::endl;
			printf("\n");
			auto t1 = std::localtime(&ctime1);
			auto t1_sec = t1->tm_sec;
			auto t1_min = t1->tm_min;
			auto t1_hour = t1->tm_hour;
			auto t1_mday = t1->tm_mday;
			auto t1_mon = t1->tm_mon + 1;
			auto t1_year = t1->tm_year + 1900;
			std::cout << t1_year << "." << t1_mon << "." << t1_mday << "." << t1_hour << "." << t1_min << "." << t1_sec << "." << std::endl;
		}
	}


	{
		/*
			3、time_point(时间点)
		*/
		{
			{
				/*
					在clocks调试中我们已经使用std::chrono::system_clock::now()来获取时间点,
					也知道std::chrono::system_clock::time_point的类型为:
					std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<__int64, std::ratio<1,10000000>>>
					这个duration我们并不常用,因此我们会自定义std::chrono::time_point类型
					这里我们定义一个以天为单位的time_point
					我们
				*/
				using day_dura = std::chrono::duration<int, std::ratio<60 * 60 * 24>>;//自定义duration
				using day_time_point = std::chrono::time_point<std::chrono::system_clock, day_dura>;//自定义time_point
				day_time_point time_point1 = std::chrono::time_point_cast<day_dura>(std::chrono::system_clock::now());//获取当前时间点,然后用time_point_cast转换到我们自定义的时间点单位
				auto cnt = time_point1.time_since_epoch().count();//time_since_epoch就是得到当前时间点距离1970.1.1有多少的持续时间duration
				//std::cout << "time_point1 is: " << time_point1 << std::endl;//时间点不能打印
				std::cout << "cnt is: " << cnt << std::endl;
				printf("\n");
			}


			{
				/*
					程序中常用的以毫秒ms为单位的time_point的使用
				*/
				using ms_time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>;
				auto time_point1 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
				std::this_thread::sleep_for(std::chrono::milliseconds(100));
				auto time_point2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
				auto takeTime = (time_point2 - time_point1).count();
				printf("\n");
			}
		}
	}

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值