2012-03-29 228 views
1

我們使用以下方法將日誌寫入日誌文件。日誌條目保存在一個名爲m_LogList的向量中(stl字符串條目保存在向量中)。當矢量的大小超過100時調用該方法。如果我們調用FlushLog方法,Log服務器的CPU利用率大約爲20-40%。如果我們註釋掉FlushLog方法,CPU利用率會下降到10-20%的範圍。
我可以使用哪些優化來降低CPU利用率?我們使用fstream的對象寫日誌記錄到文件CPU利用率高

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

調用矢量「列表」有點令人誤解。 – MSalters 2012-03-29 12:32:04

+0

如果你的CPU利用率增加了這麼多,你必須有一臺有限的機器,或者你經常調用FlushLog?製作關鍵部分相當昂貴,但我認爲這是您需要的。 – Rolle 2012-03-29 12:40:34

回答

3

我會用第一種優化是刪除.c_str()<< m_LogList[i].c_str()。它強制operator<<做一個strlen(O(n)),而不是依靠string::size(O(1))。

此外,我只是總結字符串大小,而不是調用tellp

最後,<< endl在每一行包括一個刷新。只需使用<< '\n'。你已經有了沖洗結束。

3

我會考慮首先在一個STDLIB通話傾銷日誌是這樣的:

std::copy(list.begin(), list.end(), std::ostream_iterator<std::string>(m_ofstreamLogFile, "\n")); 

這將消除因ENDL和不必要的轉換至C字符串的沖洗。 CPU方面,這應該是非常有效的。

你可以事後做備份,除非你真的關心一個非常具體的限制,但即使在這種情況下,我會說:備份在一些較低的閾值,以便你可以解釋一些溢出。

此外,刪除if(0 < m_LogList.size()),它不是真的有必要的。

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和刷新這個流。你不想這樣做,因爲你在循環結束時正在沖洗它。