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

    摸了,下次一定

  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/tuapu/p/13873717.html
Copyright © 2011-2022 走看看