我们使用以下方法将日志写入日志文件。日志条目保存在名为m_LogList的向量中(stl字符串条目保存在向量中)。当向量的大小大于100时,调用该方法。如果我们调用FlushLog方法,则Log服务器的CPU利用率约为20-40%。如果我们注释掉FlushLog方法,CPU利用率会下降到10-20%范围 我可以使用哪些优化来降低CPU利用率?我们使用fstream对象将日志条目写入文件
void CLogFileWriter::FlushLog()
{
CRCCriticalSectionLock lock(m_pFileCriticalSection);
//Entire content of the vector are writing to the file
if(0 < m_LogList.size())
{
for (int i = 0; i < (int)m_LogList.size(); ++i)
{
m_ofstreamLogFile << m_LogList[i].c_str()<<endl;
m_nSize = m_ofstreamLogFile.tellp();
if(m_pLogMngr->NeedsToBackupFile(m_nSize))
{
// Backup the log file
}
}
m_ofstreamLogFile.flush();
m_LogList.clear(); //Clearing the content of the Log List
}
}
答案 0 :(得分:3)
我要使用的第一个优化是将.c_str()
放入<< m_LogList[i].c_str()
。它强制operator<<
执行strlen
(O(n))而不是依赖string::size
(O(1))。
另外,我只是对字符串大小求和,而不是调用tellp
。
最后,<< endl
在每一行都包含一个刷新。只需使用<< '\n'
即可。你最后已经有了冲洗。
答案 1 :(得分:3)
我首先考虑将日志转储到一个stdlib调用中,如下所示:
std::copy(list.begin(), list.end(), std::ostream_iterator<std::string>(m_ofstreamLogFile, "\n"));
由于endl和不必要的转换为c字符串,这将删除刷新。在CPU方面,这应该非常有效。
你可以在事后进行备份,除非你真的关心一个非常具体的限制,但即使在这种情况下,我也会说:备份一些较低的阈值,这样你就可以解决一些溢出问题。
此外,删除if(0 < m_LogList.size())
,这对任何事情都没有必要。
答案 2 :(得分:0)
一些评论:
if(0 < m_LogList.size())
应该是:
if(!m_LogList.empty())
虽然使用vector
但它不应该有所作为。
另外你应该考虑移动
m_nSize = m_ofstreamLogFile.tellp();
if(m_pLogMngr->NeedsToBackupFile(m_nSize)) { /*...*/ }
离开循环。你没有说它使用了多少CPU,但我敢打赌它很重。
您也可以使用迭代器进行迭代:
for (int i = 0; i < (int)m_LogList.size(); ++i)
应该是:
for (std::vector<std::string>::iterator it = m_LogList.begin();
it != m_LogList.end(); ++it)
最后,更改一行:
m_ofstreamLogFile << m_LogList[i].c_str()<<endl;
分为:
m_ofstreamLogFile << m_LogList[i] << '\n';
.c_str()
是不必要的。 endl
写入EOL并刷新流。你不想这样做,因为你在循环结束时正在冲洗它。