zoukankan      html  css  js  c++  java
  • VC++程序运行时间测试函数

    0:介绍

           我们在衡量一个函数运行时间,或者判断一个算法的时间效率,或者在程序中我们需要一个定时器,定时执行一个特定的操作,比如在多媒体中,比如在游戏中等,都会用到时间函数。还比如我们通过记录函数或者算法开始和截至的时间,然后利用两者之差得出函数或者算法的运行时间。编译器和操作系统为我们提供了很多时间函数,这些时间函数的精度也是各不相同的,所以,如果我们想得到准确的结果,必须使用合适的时间函数。现在我就介绍windows下的几种常用时间函数。

    1:Sleep函数

    使用:sleep(1000),在Windows和Linux下1000代表的含义并不相同,Windows下的表示1000毫秒,也就是1秒钟;Linux下表示1000秒,Linux下使用毫秒级别的函数可以使用usleep。

    原理:sleep函数是使调用sleep函数的线程休眠,线程主动放弃时间片。当经过指定的时间间隔后,再启动线程,继续执行代码。Sleep函数并不能起到定时的作用,主要作用是延时。在一些多线程中可能会看到sleep(0);其主要目的是让出时间片。

    精度:sleep函数的精度非常低,当系统越忙它精度也就越低,有时候我们休眠1秒,可能3秒后才能继续执行。它的精度取决于线程自身优先级、其他线程的优先级,以及线程的数量等因素。

    2:MFC下的timer事件

           使用:1.调用函数SetTimer()设置定时间隔,如SetTimer(0,100,NULL)即为设置100毫秒的时间间隔;2.在应用程序中增加定时响应函数OnTimer(),并在该函数中添加响应的处理语句,用来完成时间到时的操作。

        原理:同sleep函数一样。不同的是timer是一个定时器,可以指定回调函数,默认为OnTimer()函数。

        精度:timer事件的精度范围在毫米级别,系统越忙其精度也就越差。

    3:C语言下的Time

        使用:time_t time( time_t * timer ) : 仅使用C标准库(精确到秒)time函数是获取当前时间。

        原理:time函数主要用于获取当前时间,比如我们做一个电子时钟程序,就可以使用此函数,获取系统当前的时间。

        精度:秒级别

    4:COM对象中的COleDateTime,COleDateTimeSpan类

        使用:

    COleDateTime start_time = COleDateTime::GetCurrentTime();
    
    COleDateTimeSpan end_time = COleDateTime::GetCurrentTime()-start_time;
    While(end_time.GetTotalSeconds() < 2)
    {
      // 处理延时或定时期间能处理其他的消息
      DoSomething()
      end_time = COleDateTime::GetCurrentTime-start_time;
    
    }

    原理:以上代表延时2秒,而这两秒内我们可以循环调用DoSomething(),从而实现在延时的时候我们也能够处理其他的函数,或者消息。COleDateTime,COleDateTimeSpan是MFC中CTime,CTimeSpan在COM中的应用,所以,上面的方法对于CTime,CTimeSpa同样有效。

           精度:秒级别

    5:C语言下的时钟周期clock()

           使用:

    clock_t start = clock();
    Sleep(100);
    clock_t end = clock();
    double d = (double)(start - end) / CLOCKS_PER_SEC;

    原理:clock()是获取计算机启动后的时间间隔。 

    精度:ms级别,对于短时间内的定时或者延时可以达到ms级别,对于时间比较长的定时或者延迟精度还是不够。在windows下CLOCKS_PER_SEC为1000。

    6:Windows下的GetTickCount()

    使用:

    DWORD start = GetTickCount();
    Sleep(100);
    DWORD end = GetTickCount();

    原理:GetTickCount()是获取系统启动后的时间间隔。通过进入函数开始定时,到退出函数结束定时,从而可以判断出函数的执行时间,这种时间也并非是函数或者算法的真实执行时间,因为在函数和算法线程不可能一直占用CPU,对于所有判断执行时间的函数都是一样,不过基本上已经很准确,可以通过查询进行定时。GetTickCount()和Clock()函数是向主板BIOS要real time clock时间,会有中断产生,以及延迟问题。

    精度:WindowsNT 3.5以及以后版本精度是10ms,它的时间精度比clock函数的要高,GetTickCount()常用于多媒体中。

    7:Windows下timeGetTime

    使用:需要包含Mmsystem.h,Windows.h,加入静态库Winmm.lib.

    timeBeginPeriod(1);
    DWORD start = timeGetTime();
    Sleep(100);
    DWORD end = timeGetTime();
    timeEndPeriod(1);

    原理:timeGetTime也时常用于多媒体定时器中,可以通过查询进行定时。通过查询进行定时,本身也会影响定时器的定时精度。

    精度:毫秒,与GetTickCount()相当。但是和GetTickCount相比,timeGetTime可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度, timeBeginPeriod,timeEndPeriod必须成对出现。

    8:windows下的timeSetEvent

    使用:还记的VC下的Timer吗?Timer是一个定时器,而以上我们提到几种时间函数或者类型,实现定时功能只能通过轮训来实现,也就是必须另外创建一个线程单独处理,这样会影响定时精度,好在windows提供了内置的定时器timeSetEvent,函数原型为:

    MMRESULT timeSetEvent( UINT uDelay, //以毫秒指定事件的周期
    UINT uResolution, //以毫秒指定延时的精度,数值越小定时器事件分辨率越高。缺省值为1ms
    LPTIMECALLBACK lpTimeProc, //指向一个回调函数
    WORD dwUser, //存放用户提供的回调数据
    UINT fuEvent )// 标志参数,TIME_ONESHOT:执行一次;TIME_PERIODIC:周期性执行

    具体应用时,可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在 lpFunction回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是:任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用timeKillEvent()将之释放。

    原理:可以理解为代回调函数的timeGetTime

    精度:毫秒,timeSetEvent可以通过timeBeginPeriod,timeEndPeriod设置定时器的最小解析精度, timeBeginPeriod,timeEndPeriod必须成对出现。
    9:高精度时控函数QueryPerformanceFrequency,QueryPerformanceCounter

    使用:

    LARGE_INTEGER m_nFreq;
    LARGE_INTEGER m_nBeginTime;
    LARGE_INTEGER nEndTime;
    QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期
    QueryPerformanceCounter(&m_nBeginTime); // 开始计时
    Sleep(100);
    QueryPerformanceCounter(&nEndTime);// 结束计时
    cout << (nEndTime.QuadPart-m_nBeginTime.QuadPart)*1000/m_nFreq.QuadPart<<"ms" << endl;

    原理:CPU上也有一个计数器,以机器的clock为单位,可以通过rdtsc读取,而不用中断,因此其精度与系统时间相当。

    精度:计算机获取硬件支持,精度比较高,可以通过它判断其他时间函数的精度范围。

    10:小结

      以上提到常用的9种时间函数,由于他们的用处不同,所以他们的精度也不尽相同,所以如果简单的延时可以用sleep函数,稍微准确的延时可以使用clock函数,GetTickCount函数,更高级的实用timeGetTime函数;简单的定时事件可以用Timer,准确地可以用timeSetEvent;或取一般系统时间可以通time,或者CTime,或者COleDateTime,获取准确的时间可以用clock,或者GetTickCount函数,或者timeGetTime函数,而获取准确地系统时间要使用硬件支持的QueryPerformanceFrequency函数,QueryPerformanceCounter函数。

      参考链接:VC++ 获取系统时间、程序运行时间(精确到秒,毫秒)的五种方法

  • 相关阅读:
    Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法输入日志标题
    Linux下安装oracle数据库提示DISPLAY not set. Please set the DISPLAY and try again。
    redhat 关机注销命令详解
    VirtualBox的四种网络连接方式
    修改RedHat的系统显示时间
    insufficient memory to configure kdump(没有足够的内存)解决方法(待验证、待解决)
    xen坑随笔 heartbeat dpkg垃圾数据库清除
    tomcat 监控脚本
    负载均衡随笔
    GIT命令介绍
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/8717427.html
Copyright © 2011-2022 走看看