"stat"功能更新慢?
The updating for "stat" function is slow?
代码片段:
void CMyLogger::Log(
LogLevel level, LPCTSTR file, INT line, LPCTSTR func, LPCTSTR format, ...)
{
time_t tCurrentLogTime;
time(&tCurrentLogTime);
tm tmCurrentLogTime;
localtime_s(&tmCurrentLogTime, &tCurrentLogTime);
// Check the date is changed
if (m_tmCurrentLogTime.tm_year == tmCurrentLogTime.tm_year
&& m_tmCurrentLogTime.tm_mon == tmCurrentLogTime.tm_mon
&& m_tmCurrentLogTime.tm_mday == tmCurrentLogTime.tm_mday)
{
// Check the log file size has exceeded the maximum size
struct _stat st;
_tstat(m_szCurrentLogFile, &st);
if (st.st_size > m_nMaxLogSize)
{
m_nCurrentLogIndex++;
GetCurrentLogFile();
CLogger::ClearOutputStreams();
// Add logger
AddOutputStream(new std::tofstream(m_szCurrentLogFile), true, LogLevel::Info);
}
}
// The date is changed
else
{
// Get current log time
memcpy(&m_tmCurrentLogTime, &tmCurrentLogTime, sizeof(tmCurrentLogTime));
m_nCurrentLogIndex = 0;
DeleteOldFiles();
GetCurrentLogFile();
CLogger::ClearOutputStreams();
// Add logger
AddOutputStream(new std::tofstream(m_szCurrentLogFile), true, LogLevel::Info);
}
// Log
va_list args;
va_start(args, format);
int length = _vsctprintf(format, args ) + 1;
TCHAR* text = new TCHAR[length];
_vstprintf_s(text, length, format, args);
va_end(args);
CLogger::Log(level, file, line, func, text);
delete [] text;
}
以上是日志程序的代码片段。如果日志文件超过 1 MB,则创建新的日志文件。 (xxx_000.log => xxx_001.log ...) 我写了下面的代码来测试当日志文件超过 1 MB 时是否创建新的日志文件:
#ifdef UNICODE
#define LOG(level, format, ...) CEagleLogger::GetInstance()->Log(level, __FILEW__, __LINE__, __FUNCTIONW__, format, __VA_ARGS__);
#else
#define LOG(level, format, ...) CEagleLogger::GetInstance()->Log(level, __FILE__, __LINE__, __FUNCTION__, format, __VA_ARGS__);
#endif
// ...
while (1)
LOG(LogLevel::Info, _T("================================================================================"));
但是,日志文件并不是每 1 MB 创建一次。在写入日志之前,日志文件大小被检查为 stat
函数。当实际日志文件大小超过 1 MB 时,'stat' 函数不会超过 1 MB。 “stat”功能更新慢?
stat
是一个 POSIX 函数。 _tstat
是一个 Windows 函数,旨在帮助将 POSIX 代码移植到 Windows(但是 _t 东西阻碍了其他方式的移植)。不要指望此类包装器具有最佳性能。
特别是,stat
等同于 Windows 上的 FindFirstFile
,Visual Studio 中包含的 CRT 代码证实了这一点:[= 中的第一个系统调用14=] 是 FindFirstFileEx(FindExInfoStandard ... FindExSearchNameMatch)
。 .它为您提供目录条目的许多属性,包括目录中的文件大小。对于正在写入的文件,该信息已过时。 GetFileSize
has the correct size
(请注意,_stat
也做了很多工作来获取您甚至不想要的各种属性。这在 UNIX 上相当便宜,但在 Windows必须模拟文件访问权限的东西。也不快。)
代码片段:
void CMyLogger::Log(
LogLevel level, LPCTSTR file, INT line, LPCTSTR func, LPCTSTR format, ...)
{
time_t tCurrentLogTime;
time(&tCurrentLogTime);
tm tmCurrentLogTime;
localtime_s(&tmCurrentLogTime, &tCurrentLogTime);
// Check the date is changed
if (m_tmCurrentLogTime.tm_year == tmCurrentLogTime.tm_year
&& m_tmCurrentLogTime.tm_mon == tmCurrentLogTime.tm_mon
&& m_tmCurrentLogTime.tm_mday == tmCurrentLogTime.tm_mday)
{
// Check the log file size has exceeded the maximum size
struct _stat st;
_tstat(m_szCurrentLogFile, &st);
if (st.st_size > m_nMaxLogSize)
{
m_nCurrentLogIndex++;
GetCurrentLogFile();
CLogger::ClearOutputStreams();
// Add logger
AddOutputStream(new std::tofstream(m_szCurrentLogFile), true, LogLevel::Info);
}
}
// The date is changed
else
{
// Get current log time
memcpy(&m_tmCurrentLogTime, &tmCurrentLogTime, sizeof(tmCurrentLogTime));
m_nCurrentLogIndex = 0;
DeleteOldFiles();
GetCurrentLogFile();
CLogger::ClearOutputStreams();
// Add logger
AddOutputStream(new std::tofstream(m_szCurrentLogFile), true, LogLevel::Info);
}
// Log
va_list args;
va_start(args, format);
int length = _vsctprintf(format, args ) + 1;
TCHAR* text = new TCHAR[length];
_vstprintf_s(text, length, format, args);
va_end(args);
CLogger::Log(level, file, line, func, text);
delete [] text;
}
以上是日志程序的代码片段。如果日志文件超过 1 MB,则创建新的日志文件。 (xxx_000.log => xxx_001.log ...) 我写了下面的代码来测试当日志文件超过 1 MB 时是否创建新的日志文件:
#ifdef UNICODE
#define LOG(level, format, ...) CEagleLogger::GetInstance()->Log(level, __FILEW__, __LINE__, __FUNCTIONW__, format, __VA_ARGS__);
#else
#define LOG(level, format, ...) CEagleLogger::GetInstance()->Log(level, __FILE__, __LINE__, __FUNCTION__, format, __VA_ARGS__);
#endif
// ...
while (1)
LOG(LogLevel::Info, _T("================================================================================"));
但是,日志文件并不是每 1 MB 创建一次。在写入日志之前,日志文件大小被检查为 stat
函数。当实际日志文件大小超过 1 MB 时,'stat' 函数不会超过 1 MB。 “stat”功能更新慢?
stat
是一个 POSIX 函数。 _tstat
是一个 Windows 函数,旨在帮助将 POSIX 代码移植到 Windows(但是 _t 东西阻碍了其他方式的移植)。不要指望此类包装器具有最佳性能。
特别是,stat
等同于 Windows 上的 FindFirstFile
,Visual Studio 中包含的 CRT 代码证实了这一点:[= 中的第一个系统调用14=] 是 FindFirstFileEx(FindExInfoStandard ... FindExSearchNameMatch)
。 .它为您提供目录条目的许多属性,包括目录中的文件大小。对于正在写入的文件,该信息已过时。 GetFileSize
has the correct size
(请注意,_stat
也做了很多工作来获取您甚至不想要的各种属性。这在 UNIX 上相当便宜,但在 Windows必须模拟文件访问权限的东西。也不快。)