Original link: LongAdder vs AtomicLong / LinkedIn.
The performance difference is real.
But does it matter?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Supplier;
public class AtomicAdd {
private static final int NTHREADS = 1_000;
private static final int N = 100_000_000;
private static final int REP = 1_000;
private static long test(String lbl, Runnable f, Supplier<Long> res) throws InterruptedException {
long t1 = System.currentTimeMillis();
ExecutorService es = Executors.newFixedThreadPool(NTHREADS);
for(int i = 0; i < N / REP; i++) es.submit(f);
es.shutdown();
es.awaitTermination(1, TimeUnit.HOURS);
long t2 = System.currentTimeMillis();
System.out.printf("%s : %d (%d)\n", lbl, t2 - t1, res.get());
return t2 - t1;
}
private static AtomicLong al;
private static LongAdder la;
public static void main(String[] args) throws InterruptedException {
al = new AtomicLong(0);
long al_t = test("AtomicLong", () -> { for(int i = 0; i < REP; i++) al.incrementAndGet(); }, () -> al.get());
la = new LongAdder();
long la_t = test("LongAdder", () -> { for(int i = 0; i < REP; i++) la.increment(); }, () -> la.sum());
System.out.printf("dif pr it : %d ns", ((al_t - la_t) * 1_000_000) / N);
}
}
outputs:
AtomicLong : 7550 (100000000) LongAdder : 301 (100000000) dif pr it : 72 nsX20 is impressive but only 75 nanoseconds per add is not much (numbers rounded).