PerformanceProfiler.h
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了潼關(guān)免費(fèi)建站歡迎大家使用!#pragma once #include <iostream> #include <string> #include <map> #include <algorithm> #include <stdarg.h> #include <time.h> #include <assert.h> //C++ 11 #include <unordered_map> #include <thread> #include <mutex> #ifdef _WIN32 #include <windows.h> #else #include <pthread.h> #endif using namespace std; //////////////////////////////////////////////////////// typedef long long LongType; //單例的基類——餓漢模式 template<class T> class Singleton { public: static T* GetInstance() { assert(_sInstance); return _sInstance; } protected: static T* _sInstance; }; template<class T> T* Singleton::_sInstance = new T; //////////////////////////////////////////////////// class SaveAdapter { public: virtual void Save(const char* format, ...) = 0; }; class ConsoleSaveAdapter :public SaveAdapter { public: 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 = fopen(filename, "w"); assert(_fout); } ~FileSaveAdapter() { if (_fout) fclose(_fout); } protected: //防拷貝 FileSaveAdapter(FileSaveAdapter&); FileSaveAdapter& operator=(FileSaveAdpter&); protected: FILE* _fout; }; class SqlSaveAdapter : public SaveAdapter {}; //配置管理 enum ConfigOptions { NONE = 0, //不作剖析 PERFORMANCE_PROFILER = 1, //開啟剖析 SAVE_TO_CONSOLE = 2, //保存到控制臺 SAVE_TO_FILE = 4, //保存到文件 SORT_BY_COSTTIME = 8, //按調(diào)用次數(shù)排序 SORT_BY_CALLCOUNT = 16, //按花費(fèi)時(shí)間排序 }; class ConfigManager : public Singleton<ConfigManager> { public: void SetOptions(int options) { _options = options; } void AddOption(int option) { _options |= option; } void DelOption(int option) { _options &= (~option); } int GetOptions() { return _options; } protected: friend class Singleton<ConfigManager>; ConfigManager() :_options(NONE) {} ConfigManager(const ConfigManager&); ConfigManager& operator=(const ConfigManager); protected: int _options }; //Performance Profiler struct PPNode { string _filename; string _function; size_t _line; string _desc; //附加描述信息 PPNode(const char* filename, const char* function,\ size_t line, const char* desc) :_filename(filename) ,_function(function) ,_line(line) ,_desc(desc) {} bool operator==(const PPNode& node) const { if (_line == node._line &&\ _function == node._function &&\ _filename == node._filename) return true; else return false; } }; struct PPSection { PPSection() :_totalCostTime(0) ,_totalCallCount(0) ,_totalRefCount(0) {} void Begin(int id); void End(int id); map<int, LongType> _beginTimeMap; map<int, LongType> _costTimeMap; map<int, LongType> _callCountMap; map<int, LongType> _refCountMap; LongType _totalBeginTime; //開始時(shí)間 LongType _totalCostTime; //花費(fèi)時(shí)間 LongType _totalCallCount; //調(diào)用次數(shù) LongType _totalRefCount; //引用計(jì)數(shù),解決遞歸問題 mutex _mtx; }; //PPNode計(jì)算哈希值的仿函數(shù) struct PPNodeHash { static size_t BKDRHash(const char * str) { unsigned int seed = 131; // 31 131 1313 13131 131313 unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } size_t operator()(const PPNode& node) const { static string hash; hash = node._desc; hash += node._function; return BKDRHash(hash.c_str()); } }; class PerformanceProfiler : public Singleton<PerformanceProfiler> { typedef unordered_map<PPNode, PPSection*, PPNodeHash> PP_MAP; public: PPSection* CreateSection(const char* filename, const char* function, \ size_t line, const char* desc); void OutPut(); protected: void _OutPut(SaveAdapter& sa); friend class Singleton<PerformanceProfiler>; PerformanceProfiler(){} PerformanceProfiler(const PerformanceProfiler&); PerformanceProfiler& operator=(const PerformanceProfiler&); protected: //map<PPNode, PPSection*> _ppMap; //統(tǒng)計(jì)資源信息的容器 PP_MAP _ppMap; mutex _mtx; }; struct Report { ~Report() { PerformanceProfiler::GetInstance()->OutPut(); } }; static int GetTheadId() { #ifdef _WIN32 return GetCurrentThreadId(); #else return thread_self(); #endif // _WIN32 } //剖析單線程場景 #define PERFORMANCE_PROFILER_EE_ST_BEGIN(sign, desc) \ PPSection* ps##sign = NULL; \ if (ConfigManager::GetInstance()->GetOptions() & PERFORMANCE_PROFILER) \ { \ ps##sign = PerformanceProfiler::GetInstance()->CreateSection(__FILE__, __FUNCTION__, __LINE__, desc);\ ps##sign->Begin(-1); \ } \ #define PERFORMANCE_PROFILER_ST_END(sign) \ if (ps##sign) \ ps##sign->End(-1); \ //剖析多線程場景 #define PERFORMANCE_PROFILER_EE_MT_BEGIN(sign, desc) \ PPSection* ps##sign = NULL; \ if (ConfigManager::GetInstance()->GetOptions() & PERFORMANCE_PROFILER) \ { \ ps##sign = PerformanceProfiler::GetInstance()->CreateSection(__FILE__, __FUNCTION__, __LINE__, desc);\ ps##sign->Begin(GetTheadId()); \ } \ #define PERFORMANCE_PROFILER_ST_END(sign) \ if (ps##sign) \ \ ps##sign->End(GetTheadId()); #define SET_CONFIG_OPTIONS(option) \ ConfigManager::GetInstance()->SetOptions(option);
PerformanceProfiler.cpp
#include "PerformanceProfiler.h" void PPSection::Begin(int id) { if (id != -1) //多線程 { lock_guard<mutex> lock(_mtx); //統(tǒng)計(jì)線程總的花費(fèi)時(shí)間和調(diào)用次數(shù) if (_refCountMap[id]++ == 0) _beginTimeMap[id] = clock(); } else //單線程 { if (_totalRefCount++ == 0) _totalBeginTime = clock(); } } void PPSection::End(int id) { if (id != -1) //多線程 { lock_guard<mutex> lock(_mtx); if (--_refCountMap[id] == 0) _costTimeMap[id] += clock() - _beginTimeMap[id]; ++_callCountMap[id]; } else //單線程 { if (--_totalRefCount == 0) _totalCostTime += clock() - _totalBeginTime; ++_totalCallCount; } } PPSection* PerformanceProfiler::CreateSection(const char* filename, const char* function, size_t line, const char* desc) { PPNode node(filename, function, line, desc); PPSection* section = NULL; //RAII lock_guard<mutex> lock(_mtx); PP_MAP::iterator it = _ppMap.find(node); if (it != _ppMap.end()) { section = it->second; } else { section = new PPSection; _ppMap.insert(pair<PPNode, PPSection*>(node, section)); } return section; } void PerformanceProfiler::OutPut() { int options = ConfigManager::GetInstance()->GetOptions(); if (options & SAVE_TO_CONSOLE) { ConsoleSaveAdapter csa; _OutPut(csa); } if (options & SAVE_TO_FILE) { FileSaveAdapter fsa("PerformanceProfilerReport.txt"); _OutPut(fsa); } } void PerformanceProfiler::_OutPut(SaveAdapter& sa) { vector<PP_MAP::iterator> vInfos; PP_MAP::iterator ppIt = _ppMap.begin(); while (ppIt != _ppMap.end()) { PPSection* section = ppIt->second; map<int, LongType>::iterator timeIt; timeIt = section->_costTimeMap.begin(); while (timeIt != section->_costTimeMap.end()) { section->_totalCostTime += timeIt->second; section->_totalCallCount += section->_callCountMap[timeIt->first]; ++timeIt; } vInfos.push_back(ppIt); ++ppIt; } struct SortByCostTime { bool operator()(PP_MAP::iterator l, PP_MAP::iterator r) const { return (l->second->_totalCostTime) > (r->second->_totalCostTime); } }; //按花費(fèi)時(shí)間排序 sort(vInfos.begin(), vInfos.end(), SortByCostTime()); int num = 1; for (size_t i = 0; i < vInfos.size(); ++i) { ppIt = vInfos[i]; const PPNode& node = ppIt->first; PPSection* section = ppIt->second; //node信息 sa.Save("No.%d, Desc:%s\n", num++, node._desc.c_str()); sa.Save("Filename:%s, Line:%d, Function:%s\n", node._filename.c_str(), node._line, node._function.c_str()); //section信息 map<int, LongType>::iterator timeIt; timeIt = section->_costTimeMap.begin(); while (timeIt != section->_costTimeMap.end()) { int id = timeIt->first; sa.Save("Thread:%d, CostTime:%.2f s, CallCount:%lld\n", id, (double)timeIt->second / 1000, section->_callCountMap[id]); section->_totalCostTime += timeIt->second; section->_totalCallCount += section->_callCountMap[id]; ++timeIt; } sa.Save("TotalCostTime:%.2f s, TotalCallCount:%lld, AverCostTime:%lld ms\n\n", (double)section->_totalCostTime / 1000, section->_totalCallCount, section->_totalCostTime / section->_totalCallCount); ++ppIt; } }
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
新聞標(biāo)題:性能剖析器項(xiàng)目-創(chuàng)新互聯(lián)
當(dāng)前路徑:http://jinyejixie.com/article4/depioe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、網(wǎng)站內(nèi)鏈、App開發(fā)、面包屑導(dǎo)航、移動網(wǎng)站建設(shè)、域名注冊
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容