title: AtomicInteger implementation and code duplication
body: <p><em>Warning: the question is a little long, but the part below the separation line is for curiosity only.</em></p>
  
  <p>Oracle's JDK 7 implementation of <a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicInteger.html" rel="noreferrer">AtomicInteger</a> includes the following methods:</p>
  
  <pre><code>public final int addAndGet(int delta) {
      for (;;) {
          int current = get();
          int next = current + delta;         // Only difference
          if (compareAndSet(current, next))
              return next;
      }
  }
  
  public final int incrementAndGet() {
      for (;;) {
          int current = get();
          int next = current + 1;             // Only difference
          if (compareAndSet(current, next))
              return next;
      }
  }
  </code></pre>
  
  <p>It seems clear that the second method could have been written:</p>
  
  <pre><code>public final int incrementAndGet() {
      return addAndGet(1);
  }
  </code></pre>
  
  <p>There are several other examples of similar code duplication in that class. I can't think of any reasons to do that but performance considerations (*). And I am pretty sure the authors did some in-depth testing before settling on that design.</p>
  
  <p><strong>Why (or in what circumstances) would the first code perform better than the second?</strong></p>
  
  <hr>
  
  <p>(*) I could not resist but write a quick micro benchmark. It shows (post-JIT) a systematic gap of 2-4% performance in favour of <code>addAndGet(1)</code> vs <code>incrementAndGet()</code> (that is admittedly small, but it is very consistent). I can't really explain that result either to be honest...</p>
  
  <p>Output:</p>
  
  <blockquote>
    <p>incrementAndGet(): 905<br>
    addAndGet(1): 868<br>
    incrementAndGet(): 902<br>
    addAndGet(1): 863<br>
    incrementAndGet(): 891<br>
    addAndGet(1): 867<br>
    ...</p>
  </blockquote>
  
  <p>Code:</p>
  
  <pre><code>public static void main(String[] args) throws Exception {
      final int size = 100_000_000;
      long start, end;
      AtomicInteger ai;
  
      System.out.println("JVM warmup");
      for (int j = 0; j &lt; 10; j++) {
          start = System.nanoTime();
          ai = new AtomicInteger();
          for (int i = 0; i &lt; size / 10; i++) {
              ai.addAndGet(1);
          }
          end = System.nanoTime();
          System.out.println("addAndGet(1): " + ((end - start) / 1_000_000));
          start = System.nanoTime();
          ai = new AtomicInteger();
          for (int i = 0; i &lt; size / 10; i++) {
              ai.incrementAndGet();
          }
          end = System.nanoTime();
          System.out.println("incrementAndGet(): " + ((end - start) / 1_000_000));
      }
  
  
      System.out.println("\nStart measuring\n");
  
      for (int j = 0; j &lt; 10; j++) {
          start = System.nanoTime();
          ai = new AtomicInteger();
          for (int i = 0; i &lt; size; i++) {
              ai.incrementAndGet();
          }
          end = System.nanoTime();
          System.out.println("incrementAndGet(): " + ((end - start) / 1_000_000));
          start = System.nanoTime();
          ai = new AtomicInteger();
          for (int i = 0; i &lt; size; i++) {
              ai.addAndGet(1);
          }
          end = System.nanoTime();
          System.out.println("addAndGet(1): " + ((end - start) / 1_000_000));
      }
  }
  </code></pre>