1+ package  org .dataloader .performance ;
2+ 
3+ import  java .time .Duration ;
4+ import  java .util .ArrayList ;
5+ import  java .util .List ;
6+ import  java .util .concurrent .ExecutionException ;
7+ import  java .util .concurrent .ExecutorService ;
8+ import  java .util .concurrent .Executors ;
9+ import  java .util .concurrent .Future ;
10+ import  java .util .concurrent .atomic .AtomicLong ;
11+ import  java .util .concurrent .atomic .LongAdder ;
12+ 
13+ public  class  AtomicVsAdder  {
14+ 
15+     private  static  final  ExecutorService  EXECUTOR  = Executors .newCachedThreadPool ();
16+ 
17+     public  static  void  main (final  String [] args ) throws  Exception  {
18+         // knobs 
19+         final  var  iterationsList  = List .of (1  << 20L , 1  << 24L );
20+         final  var  numberOfThreadsList  = List .of (1 , 2 , 4 , 8 , 16 );
21+         final  var  strategies  = List .of (new  LongAdderStrategy (), new  AtomicLongStrategy ());
22+ 
23+         // test 
24+         System .out .println ("testing with #cpu="  + Runtime .getRuntime ().availableProcessors ());
25+         for  (int  iterations  : iterationsList ) {
26+             for  (int  numberOfThreads  : numberOfThreadsList ) {
27+                 for  (Strategy  strategy  : strategies ) {
28+                     performTest (iterations , numberOfThreads , strategy );
29+                 }
30+             }
31+         }
32+ 
33+         EXECUTOR .shutdownNow ();
34+ 
35+     }
36+ 
37+     private  static  void  performTest (final  long  iterations , final  int  numberOfThreads , Strategy  strategy ) throws  Exception  {
38+         final  List <Future <?>> futures  = new  ArrayList <>();
39+         System .out .println ("start test with "  + iterations  + " iterations using "   + numberOfThreads  + " threads and strategy "  + strategy .getClass ().getSimpleName ());
40+         final  long  start  = System .nanoTime ();
41+ 
42+         for  (int  i  = 0 ; i  < numberOfThreads ; i ++) {
43+             Future <?> submit  = EXECUTOR .submit (() -> concurrentWork (strategy , iterations ));
44+             futures .add (submit );
45+         }
46+         for  (final  Future <?> future  : futures ) {
47+             future .get (); // wait for all 
48+         }
49+         final  long  end  = System .nanoTime ();
50+         System .out .println ("done in "  + Duration .ofNanos (end  - start ).toMillis () + "ms => result "  + strategy .get ());
51+         System .out .println ("----" );
52+         strategy .reset ();
53+     }
54+ 
55+     @ SuppressWarnings ("SameParameterValue" )
56+     private  static  void  concurrentWork (final  Strategy  strategy , final  long  iterations ) {
57+         long  work  = iterations ;
58+         while  (work -- > 0 ) {
59+             strategy .increment ();
60+         }
61+     }
62+ 
63+     interface  Strategy  {
64+         void  increment ();
65+ 
66+         long  get ();
67+ 
68+         void  reset ();
69+     }
70+ 
71+     static  class  LongAdderStrategy  implements  Strategy  {
72+ 
73+         private  LongAdder  longAdder  = new  LongAdder ();
74+ 
75+         @ Override 
76+         public  void  increment () {
77+             longAdder .increment ();
78+         }
79+ 
80+         @ Override 
81+         public  long  get () {
82+             return  longAdder .sum ();
83+         }
84+ 
85+         @ Override 
86+         public  void  reset () {
87+             longAdder  = new  LongAdder ();
88+         }
89+     }
90+ 
91+     static  class  AtomicLongStrategy  implements  Strategy  {
92+ 
93+         private  final  AtomicLong  atomicLong  = new  AtomicLong (0 );
94+ 
95+         @ Override 
96+         public  void  increment () {
97+             atomicLong .incrementAndGet ();
98+         }
99+ 
100+         @ Override 
101+         public  long  get () {
102+             return  atomicLong .get ();
103+         }
104+ 
105+         @ Override 
106+         public  void  reset () {
107+             atomicLong .set (0 );
108+         }
109+     }
110+ 
111+ }
0 commit comments