日期:2014-05-17 浏览次数:20997 次
#ifndef STAT_H #define STAT_H #include<map> #include<string> using namespace std; /*** wx,取消原有用宏方式,但测试函数的开销可能会增加测试的精度 **/ struct st_stat{ public: st_stat():call_count(0),time(0){} LARGE_INTEGER start; LARGE_INTEGER end; int call_count; __int64 time; }; /**测试函数性能或者代码块的 */ class Runnable { public: explicit Runnable(const std::string& name): _name(name) {} ~Runnable() {} const std::string& name() const { return _name; } inline void begin() ; inline void end() ; void diff_time(LONGLONG diff) { stat.time -= (stat.end.QuadPart-diff); } int getCallCount(){return stat.call_count;} __int64 getCallTime(){return stat.time;} st_stat stat; private: std::string _name; }; class test_suite { public: static test_suite& get_instance() { static test_suite me; return me; } ~test_suite(){if(fp) fclose(fp);fp=NULL; } void setWorkingDir(const std::string& val) { _working_dir = val; } const std::string& getWorkingDir() const { return _working_dir; } void setTestFilter(const std::string& val) { _test_filter = val; } const std::string& getTestFilter() const { return _test_filter; } void addTest(Runnable* test) { test_vec.insert(pair<string,Runnable*>(test->name(),test)); } void func_begin(const std::string &name); void func_end(const std::string &name); void init(const std::string &dir); void finish(); private: test_suite():fp(NULL),_working_dir(),_test_filter(){} void printHeading(); void printFooter(); void printError(const std::string&msg); std::string _working_dir; std::string _test_filter; typedef std::map<std::string,Runnable*> MAP; typedef MAP::iterator IT; typedef MAP::const_iterator const_it; MAP test_vec;//所有需要测试的函数列表 std::vector<Runnable*> none_init_vec;//没有初始化的,需要new对象,因此最后需要释放 FILE *fp; }; void call_stat_begin(st_stat*pstat); void call_stat_end(st_stat*pstat); #if defined ST_TEST_PERFORMANCE #define STAT_TEST_INIT(name) \ struct st_##name##_test: Runnable { \ st_##name##_test(): Runnable(#name) { \ test_suite::get_instance().addTest(this); \ } \ } name##_test_instance #define STAT_TEST_BEGIN(name) \ test_suite::get_instance().func_begin(#name) #define STAT_TEST_END(name) \ test_suite::get_instance().func_end(#name) #define STAT_GLOBAL_INIT(fileDir) test_suite::get_instance().init(fileDir); #define STAT_GLOBAL_FINISH() test_suite::get_instance().finish(); #else #define STAT_TEST_INIT(name) #define STAT_TEST_BEGIN(name) (void*)(0) #define STAT_TEST_END(name) (void*)(0) #define STAT_GLOBAL_INIT(fileDir) #define STAT_GLOBAL_FINISH() (void*)(0) #endif #endif
st_stat.cpp?文件
?
#include"stdafx.h" #include"st_stat.h" #ifdef _WIN32 #include<windows.h> void call_stat_begin(st_stat*pstat) { pstat->call_count++; LARGE_INTEGER large_integer; DWORD mask = 1; //DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(),mask);//特别注意,在准确测试时候是需要设置cpu亲和性,否则多核情况下不准确,这里都注释掉 BOOL bRet = ::QueryPerformanceCounter(&large_integer); //::SetThreadAffinityMask(::GetCurrentThread(),oldmask); _ASSERT(bRet); pstat->start = large_integer; } void call_stat_end(st_stat*pstat) { DWORD mask = 1; //DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(),mask); LARGE_INTEGER large_integer; BOOL bRet = ::QueryPerformanceCounter(&large_integer); _ASSERT(bRet); //::SetThreadAffinityMask(::GetCurrentThread(),oldmask); pstat->end = large_integer; pstat->time += pstat->end.QuadPart-pstat->start.QuadPart; } void Runnable::begin() { ::call_stat_begin(&stat); } void Runnable::end() { call_stat_end(&stat); } void test_suite::func_begin(const std::string & name) { // Run test initializers const_it it = test_vec.find(name); if(it!=test_vec.end()) { LARGE_INTEGER large_integer; BOOL bRet = ::QueryPerformanceCounter(&large_inte