真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

性能剖析器

 PerformanceProfiler.h:
#include
using namespace std;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

typedef long long LongType;

////////////保存適配器抽象基類//////////////
class SaveAdapter
{
public:
           //純虛函數(shù),強(qiáng)制要求派生類重寫,重新實(shí)現(xiàn)
           virtual void Save(const char* fmt, ...) = 0;
};

//控制臺(tái)保存適配器
class ConsoleSaveAdapter :public SaveAdapter//公有繼承
{
           virtual void Save(const char* format , ...)
          {
                    va_list args;
                    va_start(args, format);
                   vfprintf( stdout, format , args);//輸出重定向
                    va_end(args);
          }
};

//文件保存適配器
class FileSaveAdapter :public SaveAdapter
{
public:
          FileSaveAdapter( const char * filename)
                   :_fout(0)
          {
                   _fout = fopen( filename, "w" );
                    assert(_fout);
          }
          
          ~FileSaveAdapter()
          {
                    if (_fout)
                   {
                             fclose(_fout);
                   }
          }

           virtual void Save(const char* format , ...)
          {
                    if (_fout)
                   {
                              va_list args;
                              va_start(args, format);
                             vfprintf(_fout, format, args);//輸出重定向到_fout
                              va_end(args);
                   }
          }

protected:
           //設(shè)置為保護(hù)類型,造成scopedPtr,防拷貝
          FileSaveAdapter( const FileSaveAdapter & f);
           FileSaveAdapter& operator=(const FileSaveAdapter& f);
private:
           FILE* _fout;
};

/////////////單例基類///////////////////
//單例模式的是指就是全局的靜態(tài)指針,這個(gè)指針只能生成一個(gè)對(duì)象
template
class Singleton
{
public:
           static T * GetInstance()
          {
                    if (_sInstance == NULL )
                   {
                              lock_guard lock(_mutex);
                              if (_sInstance == NULL )
                             {
                                      _sInstance = new T ();
                             }
                   }
                    return _sInstance;
          }

protected:
           //默認(rèn)構(gòu)造函數(shù)
          Singleton()
          {}
           //成員變量
           static T * _sInstance;
           static mutex _mutex;
};

//靜態(tài)成員初始化
template
T* Singleton ::_sInstance = NULL;

template
mutex Singleton ::_mutex;

enum PP_CONFIG_OPTION
{
           PPCO_NONE = 0,               //不做剖析
           PPCO_PROFILER = 2,           //開(kāi)啟剖析
           PPCO_SAVE_TO_CONSOLE = 4,    //保存到控制臺(tái)
           PPCO_SAVE_TO_FILE = 8,       //保存到文件
           PPCO_SAVE_BY_CALL_COUNT = 16,//按調(diào)用次數(shù)降序保存
           PPCO_SAVE_BY_COST_TIME=32,   //按調(diào)用花費(fèi)時(shí)間降序保存

};


/////////////配置管理////////////////
class ConfigManager :public Singleton
{
public:
           void SetOptions(int flag)
          {
                   _flag = flag;
          }
          
           int GetOptions()
          {
                    return _flag;
          }

          ConfigManager()
                   :_flag( PPCO_PROFILER | PPCO_SAVE_TO_CONSOLE | PPCO_SAVE_TO_FILE)
          {}

private:
           int _flag;
};

///////////////獲取路徑中最后的文件名///////////////////
static string GetFileName(const string& path )
{
           char ch = '/' ;

#ifdef _WIN32
          ch = '\\';
#endif

           size_t pos = path .rfind(ch);//逆序查找
           if (pos == string ::npos)
          {
                    return path ;
          }
           else
          {
                    return path .substr(pos + 1);
          }
}

/////////性能剖析節(jié)點(diǎn)///////////
struct PPNode
{
           string _filename;//文件名
           string _function;//函數(shù)名
           int _line;       //行號(hào)
           string _desc;    //描述

          PPNode( const char * filename, const char * function, int line , const char * desc)
                   :_filename( filename)
                   , _function( function)
                   , _line( line)
                   , _desc( desc)
          {}

           bool operator<(const PPNode& node)const
          {
                    if (_line > node ._line)
                              return false ;
                    if (_line < node ._line)
                              return true ;
                    if (_filename > node ._filename)
                              return false ;
                    if (_filename < node ._filename)
                              return true ;
                    if (_function > node ._function)
                              return false ;
                    if (_function < node ._function)
                              return true ;
                    return false ;
          }

           //比較相等
           bool operator==(const PPNode& node)const
          {
                    return _function == node ._function
                             &&_line == node._line
                             &&_filename == node._filename;
          }

           //打印PPNode節(jié)點(diǎn)信息
           void Serialize(SaveAdapter & sa)const
          {
                    sa.Save("Filename:%s,Function:%s,Line:%d\n" , _filename.c_str(), _function.c_str(), _line);
          }
};


///////////////性能剖析段///////////////////////
struct PPSection
{
           friend class PerformanceProfiler;
public:
          PPSection()
                   :_beginTime(0)  
                   , _totalCostTime(0)  
                   , _totalCallCount(0)
                   , _totalRefCount(0)
          {}

           void Begin(int id)//開(kāi)始函數(shù)
          {
                    lock_guard lock(_mutex);
                   ++_callCountMap[ id];
                    if (_refCountMap[id ] == 0)
                   {
                             _beginTimeMap[ id] = clock();//計(jì)時(shí)函數(shù)
                   }
                   ++_refCountMap[ id];
                   ++_totalCallCount;
                   ++_totalRefCount;
          }

           void End(int id)
          {
                    lock_guard lock(_mutex);
                    LongType refCount = --_refCountMap[id ];
                   --_totalRefCount; //先將總的引用計(jì)數(shù)減1
                    //引用計(jì)數(shù)<=0時(shí),更新剖析段花費(fèi)的時(shí)間
                    if (refCount <= 0)
                   {
                              map:: iterator it = _beginTimeMap.find(id );
                              if (it != _beginTimeMap.end())
                             {
                                       LongType costTime = clock() - it->second;
                                       if (_refCountMap[id ] == 0)
                                      {
                                                _costTimeMap[ id] += costTime;
                                      }
                                       else
                                      {
                                                _costTimeMap[ id] = costTime;
                                      }
                                      _totalCostTime += costTime;

                             }
                   }
          }

           //線程打印信息
           void Serialize(SaveAdapter & sa)
          {
                    //如果總的引用計(jì)數(shù)不等于0,表示剖析段不匹配
                    if (_totalRefCount)
                              sa.Save("Performance Profiler Not Match!\n" );
                    //序列化效率統(tǒng)計(jì)信息
                    auto costTimeIt = _costTimeMap.begin();
                    for (; costTimeIt != _costTimeMap.end(); ++costTimeIt)
                   {
                              LongType callCount = _callCountMap[costTimeIt->first];
                              sa.Save("Thread Id:%d,Cost Time:%.2f,Call Count:%d\n",
                                      costTimeIt->first, (double)costTimeIt->second / CLOCKS_PER_SEC , callCount);
                   }
                    //CLOCKS_PER_SEC將clock函數(shù)時(shí)間轉(zhuǎn)化為以秒為單位
                    sa.Save("Total CostTime:%.2f,Total Call Count:%d\n" ,
                             ( double)_totalCostTime / CLOCKS_PER_SEC , _totalCallCount);
          }
private:
           //加鎖
           //
           //多個(gè)線程同時(shí)訪問(wèn)時(shí),每個(gè)線程的開(kāi)始時(shí)間,花費(fèi)時(shí)間,訪問(wèn)次數(shù)都不相同
           map _beginTimeMap;
           map _costTimeMap;
           map _callCountMap;
           map _refCountMap; //利用引用計(jì)數(shù)方式解決遞歸時(shí)的計(jì)時(shí)問(wèn)題
          
           //總的
           int _beginTime;//總的開(kāi)始時(shí)間
           LongType _totalCostTime; //花費(fèi)時(shí)間
           LongType _totalCallCount;//調(diào)用次數(shù)
           LongType _totalRefCount;//引用次數(shù)

           //鎖
           mutex _mutex;
};

///////////獲取當(dāng)前線程id////////////////
static int GetThreadId()
{
#ifdef _WIN32
           return ::GetCurrentThreadId();
#else
           return ::thread_self();
#endif
}


//性能剖析器
class PerformanceProfiler :public Singleton
{
public:
           friend class Singleton< PerformanceProfiler>;
           PPSection* CreateSection(const char* filename, const char * function,
                    int line, const char* desc);
           static void OutPut();

protected:
           static bool CompareByCallCount(map< PPNode, PPSection*>::iterator lhs, map< PPNode, PPSection *>::iterator rhs);
           static bool CompareByCostTime(map< PPNode, PPSection*>::iterator lhs, map< PPNode, PPSection *>::iterator rhs);

          PerformanceProfiler()
          {
                    //程序結(jié)束時(shí)輸出剖析結(jié)果
                   atexit(OutPut);
                   time(&_beginTime);
          }

           //輸出序列化信息
           //為了有效使用了vector能夠調(diào)用sort排序,只要自己添加Compare仿函數(shù)
           void _Output(SaveAdapter & sa)
          {
                    sa.Save("=====================Performance Profiler Report====================\n\n");
                    sa.Save("Profiler Begin Time:%s\n",ctime(&_beginTime));
                    unique_lock lock(_mutex);
                    vector::iterator > vInfos;

                    //PPSection作為查詢值,里面保存運(yùn)行時(shí)間,運(yùn)行次數(shù),開(kāi)始時(shí)間和結(jié)束時(shí)間
                    auto it = _ppMap.begin();
                    for (; it != _ppMap.end(); ++it)
                   {
                             vInfos.push_back(it);
                   }
                   
                    //按配置條件對(duì)剖析結(jié)果進(jìn)行排序輸出
                    int flag = ConfigManager ::GetInstance()->GetOptions();
                    if (flag&PPCO_SAVE_BY_COST_TIME )
                             sort(vInfos.begin(), vInfos.end(), CompareByCostTime);
                    else
                             sort(vInfos.begin(), vInfos.end(), CompareByCallCount);
                    for (int index = 0; index < vInfos.size(); ++index)
                   {
                              sa.Save("NO%d. Delciption:%s\n" , index + 1, vInfos[index]->first._desc.c_str());
                             vInfos[index]->first.Serialize( sa);
                             vInfos[index]->second->Serialize( sa);
                              sa.Save("\n" );
                   }
                     sa.Save("================================end==============================\n\n" );
          }
private:
           map _ppMap;
           time_t _beginTime;
           mutex _mutex;
};


//////////atexit函數(shù)/////////
struct Release
{
          ~Release()
          {
                    PerformanceProfiler::GetInstance()->OutPut();
          }
};

/////性能剖析階段開(kāi)始/////
#define PERFORMANCE_PROFILER_EE_BEGIN (sign,desc) \
           PPSection* sign##section = NULL ;  \
if (ConfigManager::GetInstance()->GetOptions()&PPCO_PROFILER)\
{\
          sign##section = PerformanceProfiler ::GetInstance()->CreateSection(__FILE__, __FUNCTION__, __LINE__ , desc); \
          sign##section->Begin(GetThreadId()); \
}

#define PERFORMANCE_PROFILER_EE_END (sign)  \
if (sign##section)\
          sign##section->End(GetThreadId());

//設(shè)置剖析選項(xiàng)
#define SET_PERFORMANCE_PROFILER_OPTIONS (flag)\
           ConfigManager::GetInstance()->SetOptions(flag);

###########################################################################################

PerformanceProfiler.cpp:

#include"performanceProfiler.h"

PPSection* PerformanceProfiler ::CreateSection(const char* filename, const char* function,
           int line , const char* desc )
{
           //第一次必須進(jìn)行查找
           PPSection* pps = NULL ;
           PPNode node(filename , function, line, desc );
           unique_lock lock(_mutex);

           map :: iterator it = _ppMap.find(node);
           if (it != _ppMap.end())
          {
                    return it->second;
          }
           else
          {
                   pps = new PPSection ;
                   _ppMap[node] = pps;
          }
           return pps;
}

void PerformanceProfiler ::OutPut()
{
           int flag = ConfigManager ::GetInstance()->GetOptions();
           if (flag&PPCO_SAVE_TO_CONSOLE )
          {
                    ConsoleSaveAdapter csa;
                    PerformanceProfiler::GetInstance()->_Output(csa);
          }
           if (flag&PPCO_SAVE_TO_FILE )
          {
                    FileSaveAdapter fsa("PerformanceProfilerReport.txt" );
                    PerformanceProfiler::GetInstance()->_Output(fsa);
          }
}

bool PerformanceProfiler ::CompareByCallCount(map< PPNode, PPSection*>::iterator lhs, map:: iterator rhs )
{
           return lhs ->second->_totalCallCount > rhs->second->_totalCallCount;
}

bool PerformanceProfiler ::CompareByCostTime(map< PPNode, PPSection*>::iterator lhs, map:: iterator rhs )
{
           return lhs ->second->_totalCostTime > rhs->second->_totalCostTime;
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

test.cpp:
void Run(int n)
{
           while(n --)
          {
                    PERFORMANCE_PROFILER_EE_BEGIN(ntwork, "網(wǎng)絡(luò)傳輸" );
                   Sleep(1000);
                    PERFORMANCE_PROFILER_EE_END(ntwork);

                    PERFORMANCE_PROFILER_EE_BEGIN(mid, "中間邏輯" );
                   Sleep(500);
                    PERFORMANCE_PROFILER_EE_END(mid);

                    PERFORMANCE_PROFILER_EE_BEGIN(sql, "數(shù)據(jù)庫(kù)" );
                   Sleep(500);
                    PERFORMANCE_PROFILER_EE_END(sql);
          }
}

void Test()
{
           thread t1(Run, 1);
           thread t2(Run, 2);
           thread t3(Run, 3);

          t1.join();
          t2.join();
          t3.join();
}

int main()
{
          Test();
           PerformanceProfiler::GetInstance()->OutPut();
          system( "pause");
           return 0;
}

分享名稱:性能剖析器
文章鏈接:http://weahome.cn/article/jjphed.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部