windows下一个用于性能分析的打点计时C++类

  最近在改造公司旧系统代码(C++),需要查找某个函数性能底下原因,所以自己写了一个打点计时类用于性能分析,其中最主要的取时间函数getSysTimeMicros由同事(杨成)提供。

头文件 performanceCounter.h

里面时间值单位为微秒,如果计时打点超过20000个,请修改头文件中COUNTER_ARRAY_SIZE。

#pragma once
#include <stdint.h>
#define COUNTER_ARRAY_SIZE 20000
class CPerformanceCounter
{
public:
	CPerformanceCounter(const char* pInfo = NULL);
	~CPerformanceCounter();
	void debugAllElapseInfo();
	int64_t getStartTime() const;
	int64_t getAllElapseUSec();
	int getTickMaxElapseIndex();
	int getTickMinElapseIndex();
	int getCount() const;
	int64_t getTickTime(const int index);
	int64_t getTickElapseUSec(const int index);
	bool isStartCount(const int index);
	void start();
	int64_t tick();


	void debugEveryTickElapseInfo();
private:
	static int64_t getSysTimeMicros();
	void debugElapseInfo(const int64_t usedTime, const char* info = NULL);
	int64_t getValidTickElapseUSec(const int index);
	int64_t m_StartTime;
	int64_t m_EndTime;
	int m_Count;
	int64_t m_CounterTimes[COUNTER_ARRAY_SIZE];
	char m_Info[256];
};

实现文件 performanceCounter.cpp

#include "performanceCounter.h"
#include <stdio.h>
#include <sysinfoapi.h>
#include <debugapi.h>

#define EPOCHFILETIME   (116444736000000000UL)

CPerformanceCounter::CPerformanceCounter(const char* pInfo)
{
	m_StartTime = 0;
	m_EndTime = 0;
	m_Count = 0;
	if (NULL != pInfo) {
		strcpy(m_Info, pInfo);
	}
	else {
		m_Info[0] = 0;
	}
}


CPerformanceCounter::~CPerformanceCounter()
{
}
void CPerformanceCounter::debugAllElapseInfo()
{
	debugElapseInfo(getAllElapseUSec(), "All");
}

void CPerformanceCounter::debugElapseInfo(const int64_t usedTime, const char* info)
{
	int64_t temp = usedTime % 1000000;
	int second = usedTime / 1000000;
	int millise = temp / 1000;
	int micros = temp % 1000;
	char tick_expr[512] = { 0 };
	sprintf(tick_expr, "%s: %s Elpase Time=%ds,%dms,%dus\n", m_Info, NULL == info ? "" : info, second, millise, micros);
	OutputDebugStringA(tick_expr);
}

void CPerformanceCounter::start()
{
	m_Count = 0;
	m_StartTime = getSysTimeMicros();
	m_EndTime = getStartTime();
}

int64_t CPerformanceCounter::tick()
{
	int64_t tmpTime = m_EndTime;
	m_EndTime = getSysTimeMicros();
	m_CounterTimes[m_Count++] = m_EndTime;
	return m_EndTime - tmpTime;
}

void CPerformanceCounter::debugEveryTickElapseInfo()
{
	char info[20];
	for (int i = 0; i < m_Count; i++) {
		sprintf(info, "Tick %d", i + 1);
		debugElapseInfo(getTickElapseUSec(i), info);
	}
}

int64_t CPerformanceCounter::getStartTime() const
{
	return m_StartTime;
}

int64_t CPerformanceCounter::getAllElapseUSec()
{
	return m_EndTime - m_StartTime;
}

int CPerformanceCounter::getTickMaxElapseIndex()
{
	int result = -1;
	int64_t m_MaxTime = 0;
	int64_t tmpTime;
	for (int i = 0; i < m_Count; i++) {
		tmpTime = getTickElapseUSec(i);
		if (tmpTime > m_MaxTime) {
			m_MaxTime = tmpTime;
			result = i;
		}
	}
	return result;
}

int CPerformanceCounter::getTickMinElapseIndex()
{
	int result = -1;
	int64_t m_MinTime = 0x7fffffffffffff;
	int64_t tmpTime;
	for (int i = 0; i < m_Count; i++) {
		tmpTime = getTickElapseUSec(i);
		if (tmpTime < m_MinTime) {
			m_MinTime = tmpTime;
			result = i;
		}
	}
	return result;
}

int CPerformanceCounter::getCount() const
{
	return m_Count;
}

int64_t CPerformanceCounter::getTickTime(const int index)
{
	if (isStartCount(index)) {
		return 0;
	}
	return m_CounterTimes[index];
}

int64_t CPerformanceCounter::getTickElapseUSec(const int index)
{
	if (isStartCount(index)) {
		return -1;
	}
	return getValidTickElapseUSec(index);

}

int64_t CPerformanceCounter::getValidTickElapseUSec(const int index)
{
	return 0 == index ? m_CounterTimes[index] - m_StartTime : m_CounterTimes[index] - m_CounterTimes[index - 1];
}

bool CPerformanceCounter::isStartCount(const int index)
{
	return index < 0 || index > m_Count - 1;
}

int64_t CPerformanceCounter::getSysTimeMicros()
{
	// 从1601年1月1日0:0:0:000到1970年1月1日0:0:0:000的时间(单位100ns)
	FILETIME ft;
	LARGE_INTEGER li;
	GetSystemTimeAsFileTime(&ft);
	li.LowPart = ft.dwLowDateTime;
	li.HighPart = ft.dwHighDateTime;
	// 从1970年1月1日0:0:0:000到现在的微秒数(UTC时间)
	return (li.QuadPart - EPOCHFILETIME) / 10;
}

使用范例:

	CPerformanceCounter performanceCounter("Refresh Original");
	CRefreshRDBYCOriginalImpl refreshRDBYC;
	performanceCounter.start();
	for (int i = 0; i < PERFORMANCE_TEST_RUN_NUM; i++) {
		refreshRDBYC.refresh();
		performanceCounter.tick();
	}
	performanceCounter.debugEveryTickElapseInfo(); // 打印每个打点计时花费时间
	performanceCounter.debugAllElapseInfo(); // 打印所有打点计时花费时间
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值