2012-03-29 6 views
1

Wir verwenden die folgende Methode, um das Protokoll in die Protokolldatei zu schreiben. Die Protokolleinträge werden in einem Vektor mit dem Namen m_LogList (strl-Einträge werden im Vektor beibehalten) gespeichert. Die Methode wird aufgerufen, wenn die Größe des Vektors mehr als 100 beträgt. Die CPU-Auslastung des Log-Servers liegt bei 20-40%, wenn wir die FlushLog-Methode aufrufen. Wenn wir die FlushLog-Methode auskommentieren, sinkt die CPU-Auslastung auf 10-20%.
Welche Optimierungen kann ich verwenden, um die CPU-Auslastung zu reduzieren? Wir verwenden fstream Objekt für die Protokolleinträge zu schreibenCPU-Auslastung hoch

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

Das Aufrufen eines Vektors "Liste" ist ein bisschen irreführend. – MSalters

+0

Wenn Ihre CPU-Auslastung so stark ansteigt, müssen Sie entweder eine begrenzte Maschine haben oder FlushLog anrufen? Einen kritischen Abschnitt zu erstellen ist ziemlich teuer, aber ich nehme an, dass es in Ihrem Fall benötigt wird. – Rolle

Antwort

3

Die erste Optimierung Datei ich verwenden würde, ist die .c_str() in << m_LogList[i].c_str() fallen zu lassen. Er zwingt operator<<, eine strlen (O (n)) statt string::size (O (1)) zu tun.

Auch ich würde nur Stringgrößen summieren, anstatt tellp anzurufen.

Schließlich enthält << endl eine Spülung, in jeder Zeile. Verwenden Sie einfach << '\n'. Sie haben bereits die Spülung am Ende.

3

würde ich vor allem das Protokoll in einem stdlib Aufruf wie folgt Dumping betrachten:

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

Dies wird die Spülung wegen Endl und die unnötigen Umwandlung in ein C-String entfernen. CPU-mäßig sollte dies sehr effizient sein.

Sie können das Backup nachher machen, es sei denn, Sie interessieren sich wirklich für ein sehr spezifisches Limit, aber selbst in diesem Fall würde ich sagen: Backup an einen niedrigeren Schwellenwert, damit Sie einen Überlauf berücksichtigen können.

Entfernen Sie auch if(0 < m_LogList.size()), es ist nicht wirklich notwendig für irgendetwas.

0

Einige Kommentare:

if(0 < m_LogList.size()) 

werden sollten:

if(!m_LogList.empty()) 

Obwohl mit einem vector sollte es keinen Unterschied machen.

Auch sollten Sie die

m_nSize = m_ofstreamLogFile.tellp(); 
if(m_pLogMngr->NeedsToBackupFile(m_nSize)) { /*...*/ } 

aus der Schleife in Erwägung ziehen. Sie sagen nicht, wie viel CPU es verbraucht, aber ich wette, es ist schwer.

könnten Sie auch mit Iteratoren iterieren:

for (int i = 0; i < (int)m_LogList.size(); ++i) 

Sollte sein:

for (std::vector<std::string>::iterator it = m_LogList.begin(); 
    it != m_LogList.end(); ++it) 

Schließlich ändern Sie die Zeile:

m_ofstreamLogFile << m_LogList[i].c_str()<<endl; 

In:

m_ofstreamLogFile << m_LogList[i] << '\n'; 

Die .c_str() ist nicht erforderlich.Und die endl schreibt eine EOL und spült den Strom. Sie möchten das nicht tun, da Sie es am Ende der Schleife spülen.