zoukankan      html  css  js  c++  java
  • C++ 计时类

    C++中的chrono

    开篇

    C中有<time.h>,而在C++中使用<chrono>来表示时间

    学习chrono之前,应该掌握两个单词:duration(时间间隔),time_point(时间点)。先从一个小例子开始讲起

    #include<iostream>
    #include<chrono>
    #include<thread>
    int main()
    {
        using namespace std::literals::chrono_literals;
        auto start = std::chrono::high_resolution_clock::now();		//获取当前时间
        std::this_thread::sleep_for(2s);					//此线程休眠2s
        auto end = std::chrono::high_resolution_clock::now();		//获取当前时间
        std::chrono::duration<float> duration = end - start;		//计算时间间隔
        std::cout << duration.count() << "s
    ";				//2.00008s
    }
    

    以上,将end以及start两个time_point相减,得到duration,最后将duration的数值打印输出

    duration 时间间隔

    由下图可以看出std::chrono::xx实际上是一个别名。说人话就是规定了d = 2000ms

    别名 实际类型(以下省略名称空间std::chrono)
    std::chrono::nanoseconds duration<long long, std::ratio<1, 1000000000>>
    std::chrono::microseconds duration<long long, std::ratio<1, 1000000>>
    std::chrono::milliseconds duration<long long, std::ratio<1, 1000>>
    std::chrono::seconds duration<long long>
    std::chrono::minutes duration<int, std::ratio<60>>
    std::chrono::hours duration<int, std::ratio<3600>>

    熟悉using的朋友应该清楚下面两行代码是等效的

    auto d1 = std::chrono::seconds(2);
    auto d2 = std::chrono::duration<long long>(2);		//代表了2s的时间间隔
    

    关于duration这个模板类,它有两个模板参数

    template<typename Rep, typename Period = std::ratio<1>>
    class duration;
    

    Rep代表时间间隔的类型,可以是doublefloatintlong long等等。

    Period代表周期,它的类型std::ratio也是一个模板类,它两个非类型模板参数,其中std::intmax_tlong long的别名

    //typedef long long intmax_t;
    template<std::intmax_t Num, std::intmax_t Denom = 1>
    class ratio;
    

    ratio可以理解为一个分数,Num代表分子,Denom代表分母,例如std::ratio<1, 20>代表$frac{1}{20}$

    durationratio的第二个模板参数都有默认值,以下方代码为例:时间间隔的类型为int,周期为$frac{1}{1000}$,表示的时间就是$100*frac{1}{1000}=0.1$,单位是秒,也就是100ms

    auto mstime = std::chrono::duration<int, std::ratio<1, 1000>>(100);		//100ms
    

    再来个例子,$30*frac{60}{1}=1800$,单位是秒,也就是30min

    auto mintime = std::chrono::duration<int, std::ratio<60>>(30);			//30min
    

    总的来说我认为std::ratioduration类中的运用可以理解成是单位,比方说std::ratio<3600>代表的就是小时(一小时有3600秒)

    扯了那么久回归正题,以下代码让本线程休眠2s

    auto d1 = std::chrono::seconds(2);
    auto d2 = std::chrono::duration<int>(2);
    std::this_thread::sleep_for(d1);		//d1和d2都是代表2s,但d1相对来说可读性更高
    

    还有另外一种方法,就是开篇中所给出的。选择哪种方式就见仁见智了

    using namespace std::literals::chrono_literals;
    std::this_thread::sleep_for(2s);	    //2s
    //std::this_thread::sleep_for(2min);        //2min
    

    time_point 时间点

    在开篇的例子中,我使用了auto来让编译器自行推断类型

    auto start = std::chrono::high_resolution_clock::now();		//获取当前时间
    //std::chrono::time_point<std::chrono::steady_clock> start;	//start是这种类型
    

    std::chrono::time_point无非就是时间点,它的模板参数接收一个“clock”

    std::chrono::high_resolution_clock 是一个很神奇的东西,它是一个别名。而且它实际是什么东西取决于库和配置。在VS中它指的就是std::chrono::steady_clock

    using std::chrono::high_resolution_clock = std::chrono::steady_clock;	//MSVC中
    using std::chrono::high_resolution_clock = std::chrono::system_clock;	//gcc的libstdc++中
    

    这就是为什么auto推断出来的startstd::chrono::time_point<std::chrono::steady_clock>类型

    根据常识,两个时间点相减的结果是一段时间间隔,所以开篇的例子是这么写的

    std::chrono::duration<float> duration = end - start;		//计算时间间隔
    

    然后再使用duration.count()得到具体的时间

    chrono的一个小应用

    设计一个计时类,在开始计时时创建出该类的一个实例,跳出作用域后调用析构函数,在控制台输出从创建到销毁所花费的时间。可以用于比较各种算法,各种拷贝等所耗费的时间

    #include<chrono>
    #include<iostream>
    class inTime
    {
        std::chrono::time_point<std::chrono::steady_clock> start, end;
        std::chrono::duration<float, std::ratio<1, 1000>> val;		//float精度的以毫秒为单位的时间间隔
    public:
        inTime() {
            start = std::chrono::high_resolution_clock::now();
        }
        ~inTime() {
            end = std::chrono::high_resolution_clock::now();
            val = end - start;
            std::cout << val.count() << "ms" << std::endl;
        }
    };
    int main()
    {
        {
            inTime it;
            Quick_Sort(vec);		//伪代码,调用一个算法,传入一个vector作为参数
        }
        //计数类离开作用域,在控制台输出所经历的时间
    }
    

    计时类的优化

    class inTime
    {
    private:
        std::chrono::high_resolution_clock::time_point start;
    public:
        inTime() : start(std::chrono::high_resolution_clock::now()) {}
        ~inTime()
        {
            Stop();
        }
        void Stop()
        {
            auto end = std::chrono::high_resolution_clock::now();
            auto _startValue = std::chrono::time_point_cast<std::chrono::microseconds>(start).
                time_since_epoch().count();
            auto _endValue = std::chrono::time_point_cast<std::chrono::microseconds>(end).
                time_since_epoch().count();			//转换成微秒,long long类型
            auto duration = _endValue - _startValue;
            std::cout << duration << "us
    ";
        }
    };
    

    杂谈(待更)

    众所周知,Debug调试模式的效率是要比Release低的,编译器会针对Release做出许多优化

    智能指针的性能问题

    unique_ptr的性能是比shared_ptr更具性能的

    C++中的random

    摸了,下次一定

  • 相关阅读:
    winform中文本框添加拖拽功能
    jQuery返回顶部代码
    判断IP地址是否在指定范围内的方法
    jQuery提示通知插件jBox
    Windows 8.1 SecureBoot未正确配置的解决方法
    操作系统下载
    js中(function(){…})()立即执行函数写法理解
    。net MVC 序列化 反序列化
    js点击button按钮跳转到页面代码
    单例模式
  • 原文地址:https://www.cnblogs.com/tuapu/p/13873717.html
Copyright © 2011-2022 走看看