boost 之计算机的时间-chrono

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 boost 之计算机的时间-chrono,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

chrono库位于名字空间boost ::chrono,需要包含头文件<boost/chrono .hpp>,为了使用扩展功能,需要定义宏 BOOST_CHRONO_EXTENSIONS,即:

#define BOOST_ERROR_CODE_HEADER_ONLY        //无需编译 system

#define BOOST_CHRONO_HEADER_ONLY                 //无需编译 chrono

#define BOOST_CHRONO_EXTENSIONS                  //使用拓展功能

#include<boost/chrono.hpp>                                        // chrono库文件

时间长度

chrono库定义了时间长度的表示 duration,在概念上与 date_time库的 time_duration相同,都表示一定长度的时间,但 duration侧重于编译期的时间单位表示,更接近ratio,所以与time_duration的接口非常不同。
 

duration

template<class Rep,class Period=ratio<1>>//默认模板参数 s
class duration
{
    public:
    typedef  Rep     rep;
    typedef  Period  period;

    private:
    rep     rep_;
    public:
    constexpr duration();
    constexpr explicit duration(const Rep2&r);
    constexpr duration(const duration&d);
    ...
}

chrono库预定义了常用的时间单位,比如 hours.minutes.seconds.milliseconds等,但与date time库time duration使用派生子类的方式不同,chrono库通过在模板参数里使用不同的ratio来定义时间单位,因而每一个时间单位都是不同的类型:

除了这些预定义的时间单位,我们也可以用typedef来简化 duration类型,实现任意勺时间分辨率,duration赋予了我们极大的灵活性。例如:
 

typedef duration<long,   std::ratio<30>>    half_min;
    typedef duration<int,    std::ratio<60*15>> quater;
    typedef duration<double, std::ratio<3600*24>> day; 

使用时间长度

duration内部只有一个成员变量rep_,用来存储时间的计数,支持各种算术运算一因为本质上它就是一个算术类型。而时间单位则用ratio在编译期表示,各种时间单位的转换都是通过ratio在编译期模板元计算完成的(具体的实现原理我们暂不必深究)。

duration 的构造函数指定它的时间计数,表示一段rep_*ratio秒的时间长度,成员函数count ()可以获得内部保存的时间计数rep_:

类型转化:

void cast()
{
    duration<int,   boost::ratio<1>> s(30);
    auto m=duration_cast<duration<int,boost::ratio<60>>>(s);
    std::cout<<m<<std::endl;
}
int main()
{
    cast();
}

时钟

时钟(Clock)是chrono里的另一个重要概念,它确定了一个时间的起点(since)和时间单位(duration),使用时钟我们就可以处理计算机世界里的时间。

chrono库实现c++标准定义

system_clock                                   :如实反映计算机实际时间的时钟;

steady_clock                                   :稳定的时钟,不会因系统时间调整而变化;

high_resolution_clock                      :高分辨率的时钟,但通常是前两者的typedef。

度量运行时间

process_real_cpu_clock:               进程执行的实际时间;

process_user_cpu_clock:               用户CPU时间; 

process_system_cpu_clock:           系统CPU时间;

thread_clock                                    :线程执行的实际时间。

各个时钟的接口基本相同 例如system_clock的类摘要

class system_clock
{
    public:
    typedef    some_define  duration;//时间单位
    typedef    duration::rep  rep;//计数单位
    typedef    duration::period period;//ratio
    typedef    chrono::time_point  time_point;//时间点;

    ...
}

使用辅助类clock_string 的两个静态成员函数name ( )、since ()可以获取时钟的描述信息,它的声明是:

template<class Clock class charT>
{
static std::basic_string<charT>name();
static std::basic_string<charT>since()
}

时间点

时间点time _point 与时钟紧密关联,它必须由一个时钟产生,标记了自时钟起点以来所经过的时间。

time_point的实例一般由now()产生 

它内部持有duration变量 支持c++标准的加减和比较运算

综合实例

高精度计时器

class steady_timer final
{
    private:
    typedef boost::chrono::steady_clock clock_type;
    typedef clock_type::time_point time_point_type;
    typedef microseconds duration_type;
     
     time_point_type m_start=clock_type::now();//记录时间点
    public:
    steady_timer()=default;
    ~steady_timer()=default;
    public:
    void restart()
    {
        m_start=clock_type::now();

    }
    duration_type elapsed() const{
        return round<duration_type>(clock_type::now()-m_start);//四舍五入
    }
};

cup_timer

为什么需要它

cpu_timer使用了chrono库的高精度时钟 high_resolution_clock,不仅能够度量进程使用的实际时间,还能够度量CPU时间,它支持最高到微秒精度的计时,而且使用起来同样非常方便,是旧版本timer的很好替代品。

是什么

时间类型

typedef boost::int_least64_t nanosecond_type;
struct cpu_times
{
    nanosecond_type wall;       //挂钟日历
    nanosecond_type user;       //用户cpu
    nanosecond_type system;     //系统cpu
};

内部实现

class cpu_timer
{
    public:
    cpu_timer(){start();}
    
    bool  is_stoped()const;
    cpu_times elapsed()const;

    ...
    //格式化 输出流逝时间
    std::string format(int placs,const std::string &format)const;
    std::string fromat(int places=default_places)const;
    ...
}

cpu_timer的实现原理与timer类似,只是内部改用chrono库的高精度时钟来获得时间计量,并且时间的计量也不是一个简单的整数类型 std::clock_t,而是改成了含有三个数值的类型cpu_times。

cpu_times没有流输出功能,但提供格式化函数format (),可以把 elapsed ()的结界钴梅为个酊漆的字符电,形如

xs wall, Ys user + Zs system = Cs CPU (P%) \n

怎么用


    std::vector<std::string>v(10,"monada");
    cpu_timer t;
    assert(!t.is_stopped());
    for(int i=0;i<10000;++i)
    {
       v.push_back("nm");
    }
    t.stop();
    assert(t.is_stopped());
    std::cout<< "pause for a while. .." <<std::endl;
    std::cout << "we can do something ..." <<std:: endl;
    t.resume();
   std:: cout<<t.format();

//定义默认的输出格式

string default_fmt(” %ws wall,%us user + %ss system = %ts CPU (%p%)\n”)

其中的%格式化选项并不是printf标准,而是cpu timer库自定义的,含义是:

%w:       挂钟时间,即cpu_times.wall值;

%u        用户时间

%s         系统时间       

%t          总计cpu时间

%p          总计时间占挂钟时间的百分比

string format(const cpu_times& times,short places,const string& format);

string format (const cpu_times& times,short places = default_places);

实例用法:

const nanoseconde_type ms=1000*1000;

cpu_times ct=(2000*ms,1000*ms,100*ms);

cout<<format(ct,7);

运结果

2.000s wall,1.000s user + 0.100s system = 1.100s cPU (55.0%)

升级版本 auto_cpu_timer

一句话 对象构建 自动计时 离开作用域 立即销毁

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129669.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!