log4cxx でパフォーマンス テストを行っています。LOG4CXX_XXXXX を直接呼び出すと、次のコードですべてのログの記録が完了するまでに約 10 秒かかります。しかし、呼び出しを boost::lockguard (重要なセクションだと思います) で囲むと、約 5 秒かかります。誰かがなぜそうであり、その逆ではないのか説明できますか.
#include "log4cxx/logger.h"
#include "log4cxx/xml/domconfigurator.h"
#include <boost/thread/thread.hpp>
#include <boost/timer/timer.hpp>
#include <boost/thread/recursive_mutex.hpp>
//#define ENHANCEDLOGGING
using namespace log4cxx;
using namespace log4cxx::helpers;
#define LOG_TMP_BUF_SIZE 3000
LoggerPtr logger(Logger::getRootLogger());
#ifdef ENHANCEDLOGGING
void LOG_DEBUG(const char *format)
{
LOG4CXX_DEBUG(logger, format);
}
#else
boost::recursive_mutex m_guard;
#define LOG_COMM 0
void LOG_DEBUG(const char *format)
{
boost::lock_guard<boost::recursive_mutex> lock(m_guard);
LOG4CXX_DEBUG(logger, format);
}
#endif
const int thread_count = 100;
void printer(void)
{
for (int i = 0; i < 4000; i++)
LOG_DEBUG("Logging performance check");
}
int main(int argc, char **argv)
{
boost::timer::auto_cpu_timer t;
xml::DOMConfigurator::configure("config.xml");
boost::thread_group threads;
for (int i = 0; i != thread_count; ++i)
threads.create_thread(printer);
threads.join_all();
std::cout << t.elapsed().user << std::endl;
std::cout << t.elapsed().wall << std::endl;
std::cout << t.elapsed().system << std::endl;
return 0;
}
次の構成を使用しています。org.apache.log4j.AsyncAppender の有無にかかわらず実行しても違いはありません
<appender name="appxNormalAppender" class="org.apache.log4j.FileAppender">
<param name="file" value="appxLogFile.log" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %C{2} (%F:%L) %t - %m%n" />
</layout>
</appender>
<appender name="async" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000"/>
<appender-ref ref="appxNormalAppender"/>
</appender>
<root>
<priority value="all" />
<appender-ref ref="appxNormalAppender"/>
</root>
</log4j:configuration>