最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++算法計時器的實現(xiàn)示例

 更新時間:2022年05月23日 09:22:10   作者:KiraFenvy  
本文主要介紹了C++算法計時器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

有時為了檢測和比較算法效率和復雜度,需要一個計時器,而這個計時器往往需要精確到毫秒ms、微秒μs甚至納秒ns,不太常用的庫或api就不放上來了。

1.毫秒級精度

1.1 CLOCKS_PER_SEC

在頭文件time.h或ctime中,clock()函數(shù)返回從“開啟這個程序進程”到“程序中調(diào)用clock()函數(shù)”時之間的CPU時鐘計時單元(clock tick)數(shù),在MSDN中稱之為掛鐘時間(wal-clock),常量CLOCKS_PER_SEC,它用來表示一秒鐘會有多少個時鐘計時單元,精確到毫秒,其使用方法如下:

精華代碼:

#include <iostream>
#include<vector>
#include <algorithm>
#include <ctime>
using namespace std;
int main()
{
    
    clock_t begin, end;
    begin = clock();
    for (int i = 1; i <= 100; ++i)
    {
       
    }
    end = clock();
    cout << "100次循環(huán)所用時間:" << double(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
       
    return 0;
}

示例為檢測二叉堆不同輸入一個一個插入所用時間(不能直接跑):

#include <iostream>
#include<vector>
#include <algorithm>
#include <ctime>
using namespace std;

int main()
{
    int num, mode;
    cout << "輸入大小和模式,其中模式1為正序,2為倒序,3位隨機" << endl;
    cout << "示例:1000 2" << endl;
    cin >> num >> mode;//輸入大小和模式,其中模式1為正序,2為倒序,3位隨機
    BinaryHeap<int> heap1,heap2;
    clock_t begin, end;
    switch (mode)
    {
    case 1://正序
        begin = clock();
        for (int i = 1; i <= num; ++i)
        {
            heap1.insert(i);
        }
        end = clock();
        cout << "一個一個正序插入所用時間:" << double(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
        break;
    case 2://倒序
        begin = clock();
        for (int i = num; i >= 1; --i)
        {
            heap1.insert(i);
        }
        end = clock();
        cout << "一個一個倒序插入所用時間:" << double(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
        break;
    case 3://正倒序交叉模擬隨機
        begin = clock();
        for (int i = 1; i<num/2; ++i)
        {
            heap1.insert(i);
            heap1.insert(num - i);
        }
        end = clock();
        cout << "一個一個隨機插入所用時間:" << double(end - begin) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
        break;
    default:
        break;
    }
  
 
    return 0;
}

1.2 GetTickCount()函數(shù) (Windows API)

GetTickCount返回(retrieve)從操作系統(tǒng)啟動所經(jīng)過(elapsed)的毫秒數(shù),它的返回值是DWORD。

#include <stdio.h>
#include <windows.h>
#include<iostream>
#pragma comment(lib, "winmm.lib") //告訴編譯器要導入winmm庫,有時候可刪

int main()
{
    DWORD t1, t2;
    t1 = GetTickCount();
    for(int i=1;i<=10000;++i)
    {
        
    }//do something
    t2 = GetTickCount();
    //printf("Use Time:%f\n", (t2 - t1) * 1.0);
    cout<<"Use Time:"<<(double)(t2-t1)<<"ms"<<endl;
    return 0;
}

1.3 timeGetTime()函數(shù)(Windows API)

以毫秒計的系統(tǒng)時間,該時間為從系統(tǒng)開啟算起所經(jīng)過的時間。在使用timeGetTime之前應先包含頭文件#include <Mmsystem.h>或#include <Windows.h>并在project->settings->link->Object/library modules中添加winmm.lib。也可以在文件頭部添加 #pragma comment( lib,"winmm.lib" )。

備注:命令行:#pragma comment( lib,"xxx.lib" )時預編譯處理指令,讓vc將winmm.lib添加到工程中去進行編譯。

//#include<stdio.h>
#include<windows.h>
#include<iostream>
#pragma comment( lib,"winmm.lib" )

int main()
{
    DWORD t1, t2;
    t1 = timeGetTime();
    foo();//do something
    t2 = timeGetTime();
    //printf("Use Time:%f\n", (t2 - t1)*1.0 / 1000);
    cout<<"Use Time:"<<(double)(t2-t1)<<"ms"<<endl;
    return 0;
}

該函數(shù)的時間精度是五毫秒或更大一些,這取決于機器的性能??捎胻imeBeginPeriod和timeEndPeriod函數(shù)提高timeGetTime函數(shù)的精度。如果使用了,連續(xù)調(diào)用timeGetTime函數(shù),一系列返回值的差異由timeBeginPeriod和timeEndPeriod決定。也可以用timeGetTime實現(xiàn)延時功能Delay

void Delay(DWORD delayTime)
{
  DWORD delayTimeBegin;
  DWORD delayTimeEnd;
  delayTimeBegin=timeGetTime();
  do
  {    
  	delayTimeEnd=timeGetTime();
  }while((delayTimeEnd-delayTimeBegin)<delayTime)
}

1.4 timeval結構體(Linux)

timeval結構體

#include <sys/time.h> 
#include <iostream> 
#include <time.h> 
double get_wall_time() 
{ 
  struct timeval time ; 
  if (gettimeofday(&time,NULL)){ 
    return 0; 
  } 
  return (double)time.tv_sec + (double)time.tv_usec * .000001; 
} 
 
int main() 
{ 
  unsigned int t = 0; 
  double start_time = get_wall_time() 
  while(t++<10e+6); 
  double end_time = get_wall_time() 
  std::cout<<"循環(huán)耗時為:"<<end_time-start_time<<"ms"; 
  return 0; 
} 

2.微秒級精度

QueryPerformanceCounter()函數(shù)和QueryPerformanceFrequency()函數(shù)(Windows API)

QueryPerformanceFrequency()函數(shù)返回高精確度性能計數(shù)器的值,它可以以微妙為單位計時,但是QueryPerformanceCounter()確切的精確計時的最小單位是與系統(tǒng)有關的,所以,必須要查詢系統(tǒng)以得到QueryPerformanceCounter()返回的嘀噠聲的頻率。QueryPerformanceFrequency()提供了這個頻率值,返回每秒嘀噠聲的個數(shù)。

//#include<stdio.h>
#include<iostream>
#include<windows.h>
#pragma comment( lib,"winmm.lib" )

int main()
{
    LARGE_INTEGER t1, t2, tc;
    QueryPerformanceFrequency(&tc);
    QueryPerformanceCounter(&t1);
    foo();//do something
    QueryPerformanceCounter(&t2);
    //printf("Use Time:%f\n", (t2.QuadPart - t1.QuadPart)*1.0 / tc.QuadPart);
    cout << "Use Time:" << (double)((t2.QuadPart - t1.QuadPart) * 1000000.0 / tc.QuadPart) << "μs" << endl;
    return 0;
}

封裝好的易于調(diào)用的代碼:

//MyTimer.h// 
#ifndef __MyTimer_H__  
#define __MyTimer_H__  
#include <windows.h>  
 
class MyTimer 
{ 
private: 
  int _freq; 
  LARGE_INTEGER _begin; 
  LARGE_INTEGER _end; 
 
public: 
  long costTime;      // 花費的時間(精確到微秒)  
 
public: 
  MyTimer() 
  { 
    LARGE_INTEGER tmp; 
    QueryPerformanceFrequency(&tmp);//QueryPerformanceFrequency()作用:返回硬件支持的高精度計數(shù)器的頻率。  
 
    _freq = tmp.QuadPart; 
    costTime = 0; 
  } 
 
  void Start()      // 開始計時  
  { 
    QueryPerformanceCounter(&_begin);//獲得初始值  
  } 
 
  void End()        // 結束計時  
  { 
    QueryPerformanceCounter(&_end);//獲得終止值  
    costTime = (long)((_end.QuadPart - _begin.QuadPart) * 1000000 / _freq); 
  } 
 
  void Reset()      // 計時清0  
  { 
    costTime = 0; 
  } 
}; 
#endif  
 
//main.cpp 
#include "MyTimer.h" 
#include <iostream> 
 
 
int main() 
{ 
  MyTimer timer; 
  unsigned int t = 0;  
  timer.Start(); 
  while (t++ < 10e+5); 
  timer.End();  
  std::cout << "耗時為:" << timer.costTime << "us"; 
  return 0 ; 
} 

3.納秒級精度

要先獲取CPU頻率。

在Intel Pentium以上級別的CPU中,有一個稱為“時間戳(Time Stamp)”的部件,它以64位無符號整型數(shù)的格式,記錄了自CPU上電以來所經(jīng)過的時鐘周期數(shù)。由于目前的CPU主頻都非常高,因此這個部件可以達到納秒級的計時精度。這個精確性是上述幾種方法所無法比擬的.在Pentium以上的CPU中,提供了一條機器指令RDTSC(Read Time Stamp Counter)來讀取這個時間戳的數(shù)字,并將其保存在EDX:EAX寄存器對中。由于EDX:EAX寄存器對恰好是Win32平臺下C++語言保存函數(shù)返回值的寄存器,所以我們可以把這條指令看成是一個普通的函數(shù)調(diào)用,因為RDTSC不被C++的內(nèi)嵌匯編器直接支持,所以我們要用_emit偽指令直接嵌入該指令的機器碼形式0X0F、0X31。

inline unsigned __int64 GetCycleCount()
{
    __asm
    {
        _emit 0x0F;
        _emit 0x31;
    }
}

void test()
{
    unsigned long t1,t2;
    t1 = (unsigned long)GetCycleCount();
    foo();//dosomething
    t2 = (unsigned long)GetCycleCount();
    printf("Use Time:%f\n",(t2 - t1)*1.0/FREQUENCY);   //FREQUENCY指CPU的頻率
}

下面為獲取CPU精度的代碼

#include<Windows.h>
LONGLONG GetFrequency(DWORD sleepTime) //獲取CPU主頻

{

    DWORD low1 = 0, high1 = 0, low2 = 0, high2 = 0;

    LARGE_INTEGER fq, st, ed;

    /*在定時前應該先調(diào)用QueryPerformanceFrequency()函數(shù)獲得機器內(nèi)部計時器的時鐘頻率。接著在

需要嚴格計時的事件發(fā)生前和發(fā)生之后分別調(diào)用QueryPerformanceCounter(),利用兩次獲得的技術

之差和時鐘的頻率,就可以計算出時間經(jīng)歷的精確時間。*/

    ::QueryPerformanceFrequency(&fq); //精確計時(返回硬件支持的高精度計數(shù)器的頻率)

    ::QueryPerformanceCounter(&st); //獲得起始時間

    __asm { //獲得當前CPU的時間數(shù)

rdtsc

mov low1, eax

mov high1, edx

    }

    ::Sleep(sleepTime); //將線程掛起片刻

    ::QueryPerformanceCounter(&ed); //獲得結束時間

    __asm {
rdtsc //讀取CPU的時間戳計數(shù)器

mov low2, eax

mov high2, edx

    }

    //將CPU得時間周期數(shù)轉(zhuǎn)化成64位整數(shù)

    LONGLONG begin = (LONGLONG)high1 << 32 | low1;

    LONGLONG end = (LONGLONG)high2 << 32 | low2;

    //將兩次獲得的CPU時間周期數(shù)除以間隔時間,即得到CPU的頻率

    //由于windows的Sleep函數(shù)有大約15毫秒的誤差,故以windows的精確計時為準

    return (end - begin) * fq.QuadPart / (ed.QuadPart - st.QuadPart);
}

4.利用chrono的各精度集成版(本質(zhì)微秒)

4.1 chrono庫介紹

函數(shù)原型:

template <class Clock, class Duration = typename Clock::duration>
  class time_point;

std::chrono::time_point 表示一個具體時間

第一個模板參數(shù)Clock用來指定所要使用的時鐘,在標準庫中有三種時鐘,分別為:

  • system_clock:當前系統(tǒng)范圍(即對各進程都一致)的一個實時的日歷時鐘(wallclock)
  • steady_clock:當前系統(tǒng)實現(xiàn)的一個維定時鐘,該時鐘的每個時間嘀嗒單位是均勻的(即長度相等)。
  • high_resolution_clock:當前系統(tǒng)實現(xiàn)的一個高分辨率時鐘。

第二個模板函數(shù)參數(shù)用來表示時間的計量單位(特化的std::chrono::duration<> )

時間點都有一個時間戳,即時間原點。chrono庫中采用的是Unix的時間戳1970年1月1日 00:00。所以time_point也就是距離時間戳(epoch)的時間長度(duration)。

4.2 代碼示例

#include <iostream>
#include <chrono>
 
using namespace std;
using namespace std::chrono;
 
class TimerClock
{
public:
 TimerClock()
 {
  update();
 }
 
 ~TimerClock()
 {
 }
 
 void update()
 {
  _start = high_resolution_clock::now();
 }
 //獲取秒
 double getTimerSecond()
 {
  return getTimerMicroSec() * 0.000001;
 }
 //獲取毫秒
 double getTimerMilliSec()
 {
  return getTimerMicroSec()*0.001;
 }
 //獲取微妙
 long long getTimerMicroSec()
 {
  //當前時鐘減去開始時鐘的count
  return duration_cast<microseconds>(high_resolution_clock::now() - _start).count();
 }
private:
 time_point<high_resolution_clock>_start;
};
 
//測試的主函數(shù)
int main()
{
 TimerClock TC;
 int sum = 0;
 TC.update();
 for (int i = 0; i > 100000; i++)
 {
  sum++;
 }
 cout << "cost time:" << TC.getTimerMilliSec() <<"ms"<< endl;
 cout << "cost time:" << TC.getTimerMicroSec() << "us" << endl;
 
 return 0;
}

5.秒級精度

單純以備不時之需,沒人用吧。

time() 函數(shù)

在頭文件time.h中,time()獲取當前的系統(tǒng)時間,只能精確到秒,返回的結果是一個time_t類型,其使用方法如下:

#include <time.h>   
#include <stdio.h>   

int main()
 {  
     time_t first, second;  
     first=time(NULL);  
     delay(2000);  
     second=time(NULL);  
     printf("The difference is: %f seconds",difftime(second,first));  //調(diào)用difftime求出時間差
     return 0;   
}

到此這篇關于C++算法計時器的實現(xiàn)示例的文章就介紹到這了,更多相關C++算法計時器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于Matlab圖像處理的公路裂縫檢測實現(xiàn)

    基于Matlab圖像處理的公路裂縫檢測實現(xiàn)

    隨著公路的大量投運,公路日常養(yǎng)護和管理已經(jīng)成為制約公路運營水平提高的瓶頸,特別是路面狀態(tài)采集、檢測維護等工作更是對傳統(tǒng)的公路運維模式提出了挑戰(zhàn)。這篇文章主要介紹了如何通過Matlab圖像處理實現(xiàn)公路裂縫檢測,感興趣的可以了解一下
    2022-02-02
  • 帶你了解C++的IO流

    帶你了解C++的IO流

    這篇文章主要介紹了C++ IO流的相關資料,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2021-09-09
  • C語言自定義類型全解析

    C語言自定義類型全解析

    在C語言中自定義類型主要有結構體類型、位段、枚舉類型、聯(lián)合體類型,自定義類型是面試常會碰到的內(nèi)容,今天我們來詳細了解一下它
    2022-02-02
  • C++11的函數(shù)包裝器std::function使用示例

    C++11的函數(shù)包裝器std::function使用示例

    C++11引入的std::function是最常用的函數(shù)包裝器,它可以存儲任何可調(diào)用對象并提供統(tǒng)一的調(diào)用接口,以下是關于函數(shù)包裝器的詳細講解,包括它的基本用法、特點、限制、以及與其他相關機制的對比
    2024-12-12
  • C++實現(xiàn)學生成績管理系統(tǒng)最新版

    C++實現(xiàn)學生成績管理系統(tǒng)最新版

    這篇文章主要為大家詳細介紹了C++實現(xiàn)學生成績管理系統(tǒng)最新版,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 北郵計算機考研復試題的C語言解答精選

    北郵計算機考研復試題的C語言解答精選

    這篇文章主要介紹了北郵計算機考研復試題目的C語言解答精選,選自2012年的一些基礎的上機題目,需要的朋友可以參考下
    2015-08-08
  • tc編譯的dos程序和vc編譯的win32控制臺程序的異同

    tc編譯的dos程序和vc編譯的win32控制臺程序的異同

    tc編譯的dos程序和vc編譯的win32控制臺程序的異同...
    2007-08-08
  • C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)

    C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++11正則表達式詳解(regex_match、regex_search和regex_replace)

    C++11正則表達式詳解(regex_match、regex_search和regex_replace)

    正則表達式(regular expression)是計算機科學中的一個概念,又稱規(guī)則表達式,下面這篇文章主要介紹了C++11正則表達式(regex_match、regex_search和regex_replace)的相關資料,需要的朋友可以參考下
    2022-09-09
  • C++編譯/編輯器對OIer的必要功能(推薦)

    C++編譯/編輯器對OIer的必要功能(推薦)

    這篇文章主要介紹了C++編譯/編輯器對OIer的必要功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04

最新評論

渭源县| 华宁县| 蓬莱市| 永德县| 娄底市| 灵石县| 察隅县| 任丘市| 叙永县| 新郑市| 高邮市| 灵山县| 琼中| 芦溪县| 安多县| 信宜市| 沛县| 临江市| 鄂托克前旗| 天峻县| 浦江县| 肇源县| 正蓝旗| 天水市| 长泰县| 南雄市| 镇沅| 甘孜| 新源县| 建德市| 嘉黎县| 句容市| 名山县| 沭阳县| 株洲市| 蛟河市| 高雄市| 微博| 丰原市| 栖霞市| 彭山县|