Files
Client/Server/RylServerProject/BaseLibrary/Utility/Debug/PerformanceCheck.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

195 lines
4.5 KiB
C++

#include "stdafx.h"
#include <utility>
#include <algorithm>
#include <functional>
#include "DebugUtils.h"
#include "PerformanceCheck.h"
CPerformanceCheck& CPerformanceCheck::GetInstance()
{
static CPerformanceCheck performanceCheck;
return performanceCheck;
}
CPerformanceCheck::CPerformanceCheck()
: m_fnPreFix(0), m_fnPostFix(0)
{
ClockPerSec(m_Frequency, Frequency);
m_fFrequency = static_cast<double>(m_Frequency.QuadPart);
}
CPerformanceCheck::~CPerformanceCheck()
{
PerformanceCheckLock::Syncronize sync(m_TableLock);
m_InstrumentTable.clear();
}
void CPerformanceCheck::SetUserMessageFunc(FnPrintUserMessage fnPreFix, FnPrintUserMessage fnPostFix)
{
m_fnPreFix = fnPreFix;
m_fnPostFix = fnPostFix;
}
inline unsigned long perf_sdbmHash(const unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++) { hash = c + (hash << 6) + (hash << 16) - hash; }
return hash;
}
void CPerformanceCheck::AddTime(const char* szfunctionName, double fEstimateTime)
{
unsigned long dwHashedKey = perf_sdbmHash(reinterpret_cast<const unsigned char*>(szfunctionName));
PerformanceCheckLock::Syncronize sync(m_TableLock);
fEstimateTime /= m_fFrequency;
std::pair<PerformanceTable::iterator, PerformanceTable::iterator> itrPair =
m_InstrumentTable.equal_range(dwHashedKey);
for(;itrPair.first != itrPair.second; ++itrPair.first)
{
Instrument& instrument = itrPair.first->second;
if(0 == strcmp(szfunctionName, instrument.m_szFunctionName))
{
// 테이블에서 찾은 경우, 값을 더한다.
instrument.m_fProcessTime += fEstimateTime;
if(instrument.m_fMinTime > fEstimateTime) { instrument.m_fMinTime = fEstimateTime; }
if(instrument.m_fMaxTime < fEstimateTime) { instrument.m_fMaxTime = fEstimateTime; }
++instrument.m_dwCalled;
return;
}
}
// 테이블에 존재하지 않는 경우, 밀어 넣는다.
m_InstrumentTable.insert(std::make_pair(dwHashedKey, Instrument(dwHashedKey, fEstimateTime, szfunctionName)));
}
bool CPerformanceCheck::PrintAllTime(const char* fileName, bool bReset)
{
if(m_InstrumentTable.empty())
{
return false;
}
char strLogPath[MAX_PATH];
char strLogFileName[MAX_PATH];
DbgUtils::SetProgramName(strLogPath, MAX_PATH, 0);
// create the directory if it doesn't exist
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strLogPath))
{
if (!CreateDirectory(strLogPath, 0))
{
return false;
}
}
// create log file name in good order
unsigned long dwSpinCount = 0;
unsigned long dwMaxFileSize = 50 * 1024 * 1024;
while(true)
{
_sntprintf(strLogFileName, MAX_PATH, "%s/PerformanceLog-%s-%05d.log",
strLogPath, fileName, dwSpinCount);
HANDLE hLogFile = CreateFile(strLogFileName, GENERIC_WRITE,
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if(INVALID_HANDLE_VALUE == hLogFile)
{
break;
}
else
{
unsigned long dwHighValue = 0;
unsigned long dwFileSize = GetFileSize(hLogFile, &dwHighValue);
CloseHandle(hLogFile);
if(dwHighValue == 0 && dwFileSize < dwMaxFileSize)
{
break;
}
}
++dwSpinCount;
}
// create log file
PerformanceCheckLock::Syncronize sync(m_TableLock);
FILE* logFile = fopen(strLogFileName, "at");
if(0 == logFile)
{
return false;
}
if(0 != m_fnPreFix)
{
m_fnPreFix(logFile);
}
fprintf(logFile,
" Average : Minimum : Maximum : Total : # : Profile Name\n"
"------------------------------------------------------------------------------------------------\n" );
double fTotalAvgTime = 0;
PerformanceTable::iterator pos;
PerformanceTable::iterator end;
for(pos = m_InstrumentTable.begin(),
end = m_InstrumentTable.end();
pos != end; ++pos)
{
const Instrument& instrument = pos->second;
if(0 == instrument.m_szFunctionName)
{
continue;
}
const double fAvgTime = (0.0f == instrument.m_fProcessTime) ?
0.0f : (instrument.m_fProcessTime / instrument.m_dwCalled); // Average
fTotalAvgTime += fAvgTime;
fprintf(logFile, " %3.6f %3.6f %3.6f %8.1f %10d %s\n",
fAvgTime, instrument.m_fMinTime, instrument.m_fMaxTime,
instrument.m_fProcessTime, instrument.m_dwCalled, instrument.m_szFunctionName);
}
fprintf(logFile, "\n\n Total AvgTime : %3.6f\n\n\n", fTotalAvgTime);
if(0 != m_fnPostFix)
{
m_fnPostFix(logFile);
}
fclose(logFile);
if(bReset)
{
for(pos = m_InstrumentTable.begin(),
end = m_InstrumentTable.end();
pos != end; ++pos)
{
pos->second.Initialize();
}
}
return true;
}