title: Log4J2 sync loggers faster than mixed async/sync loggers
body: <p>Based on <a href="https://logging.apache.org/log4j/2.x/manual/async.html" rel="nofollow noreferrer">https://logging.apache.org/log4j/2.x/manual/async.html</a> I want to use the <strong>Mixing Synchronous and Asynchronous Loggers</strong> approach in order to benefit from some performance improvement over the all synchronous loggers.</p>
  
  <p>The benchmark code:</p>
  
  <pre><code>public static void main(String[] args) {
      org.apache.logging.log4j.Logger log4j2Logger = org.apache.logging.log4j.LogManager
              .getLogger("com.foo.Bar");
  
      long start = System.currentTimeMillis();
      int nbLogMessages = 1 * 1000 * 1000;
  
      for (int i = 0; i &lt; nbLogMessages; i++) {
          log4j2Logger.info("Log Message");
      }
  
      org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) log4j2Logger;
      org.apache.logging.log4j.core.LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) coreLogger
              .getContext();
      Map&lt;String, org.apache.logging.log4j.core.Appender&gt; appenders = context
              .getConfiguration().getAppenders();
      for (org.apache.logging.log4j.core.Appender appender : appenders
              .values()) {
          appender.stop();
      }
  
      long elapsed = System.currentTimeMillis() - start;
      System.out.println("Elapsed " + elapsed + "ms "
              + (nbLogMessages * 1000 / elapsed) + "logs/sec.");
  }
  </code></pre>
  
  <p>The Log4j2 configuration is exactly the one in the doc (<a href="https://logging.apache.org/log4j/2.x/manual/async.html" rel="nofollow noreferrer">https://logging.apache.org/log4j/2.x/manual/async.html</a>):</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Configuration status="WARN"&gt;
    &lt;Appenders&gt;
      &lt;RandomAccessFile name="RandomAccessFile" fileName="/tmp/asyncWithLocation.log" immediateFlush="false" append="false"&gt;
        &lt;PatternLayout&gt;
          &lt;Pattern&gt;%d %p %class{1.} [%t] %location %m %ex%n&lt;/Pattern&gt;
        &lt;/PatternLayout&gt;
      &lt;/RandomAccessFile&gt;
    &lt;/Appenders&gt;
    &lt;Loggers&gt;
      &lt;!-- pattern layout actually uses location, so we need to include it --&gt;
      &lt;AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true"&gt;
        &lt;AppenderRef ref="RandomAccessFile"/&gt;
      &lt;/AsyncLogger&gt;
      &lt;Root level="info" includeLocation="true"&gt;
        &lt;AppenderRef ref="RandomAccessFile"/&gt;
      &lt;/Root&gt;
    &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  
  <p>With that mixed sync/async logger config I get around <strong>33,400</strong> logs/sec.</p>
  
  <p>Now if I replace the AsyncLogger "com.foo.Bar" with a regular Logger I get around <strong>35,300</strong> logs/sec.</p>
  
  <p>How come the synchronous logger strategy is faster, according to the graphs it should have a way higher throughput no?</p>
  
  <p>I've tried various other things like "warming up" the JVM before doing the benchmark like they recommend but it didn't help.</p>
  
  <p>Note that if I set the property Log4jContextSelector to "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector" to activate the "all async" loggers, I get around 86,400 logs/seconds. Unfortunately I can't use that option for other reasons.</p>
  
  <p>Using log4j2-2.3, disruptor-3.3.2.<br>
  OS is Ubuntu, 8 cores.</p>