This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* To change this template, choose Tools | Templates | |
* and open the template in the editor. | |
*/ | |
package benchmarksynchronization; | |
/** | |
* | |
* @author Tanin | |
*/ | |
public class Main { | |
/** | |
* @param args the command line arguments | |
*/ | |
public static void main(String[] args) { | |
int numOfExperiment = 100; | |
long sumSync = 0; | |
long sumNonSync = 0; | |
for (int numLoop=1;numLoop <= 1000000;numLoop*=10) { | |
long[] resultSync = new long[numOfExperiment]; | |
long[] resultNonSync = new long[numOfExperiment]; | |
for (int i=0;i<numOfExperiment;i++) { | |
resultSync[i] = benchSync(numLoop); | |
resultNonSync[i] = benchNonSync(numLoop); | |
sumSync += resultSync[i]; | |
sumNonSync += resultNonSync[i]; | |
} | |
double avgSync = (double)sumSync / numOfExperiment; | |
double avgNonSync = (double)sumNonSync / numOfExperiment; | |
System.out.print("numLoop=" +numLoop); | |
System.out.print(", Sync = " + (long)avgSync + "(" + (long)computeStd(resultSync,avgSync) + ")"); | |
System.out.print(", Non-Sync = "+ (long)avgNonSync + "(" + (long)computeStd(resultNonSync,avgNonSync) + ")"); | |
System.out.println(", Ratio = " + ((double)sumSync/sumNonSync)); | |
} | |
} | |
static double computeStd(long[] elements, double avg) { | |
double sumDiff = 0; | |
for (int i=0;i<elements.length;i++) { | |
sumDiff += ((double)elements[i] - avg) * ((double)elements[i] - avg); | |
} | |
return Math.sqrt(1.0 * sumDiff / (elements.length - 1)); | |
} | |
static long benchSync(int numLoop) | |
{ | |
int a = 0; | |
Object obj = new Object(); | |
long startTime = System.nanoTime(); | |
for (int i=0;i<numLoop;i++) | |
{ | |
synchronized(obj) { | |
a++; | |
} | |
} | |
return (System.nanoTime() - startTime); | |
} | |
static long benchNonSync(int numLoop) | |
{ | |
int a = 0; | |
Object obj = new Object(); | |
long startTime = System.nanoTime(); | |
for (int i=0;i<numLoop;i++) | |
{ | |
a++; | |
} | |
return (System.nanoTime() - startTime); | |
} | |
} |
Here is the result:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
numLoop=1, Sync = 2038(1544), Non-Sync = 1686(337), Ratio = 1.2087152971312691 | |
numLoop=10, Sync = 7838(21776), Non-Sync = 3915(2637), Ratio = 2.0018106689004207 | |
numLoop=100, Sync = 16021(8481), Non-Sync = 6042(5061), Ratio = 2.651660195363833 | |
numLoop=1000, Sync = 77951(17555), Non-Sync = 10382(10837), Ratio = 7.5077016277772906 | |
numLoop=10000, Sync = 717291(129850), Non-Sync = 27672(13501), Ratio = 25.92038803375872 | |
numLoop=100000, Sync = 6473678(761305), Non-Sync = 167752(30223), Ratio = 38.590702576996115 | |
numLoop=1000000, Sync = 42292846(27433724), Non-Sync = 1632998(220871), Ratio = 25.89888837255176 |
It is somewhat strange that ratio for 100,000 loops is bigger than for 1,000,000 loops. Maybe JVM optimizes something for us.
Now if you are going to design a system with the synchronized statement, please beware of the performance detriment.
If you do not call the synchronized more than 10,000 times (within a minute), I would just use the statement and go with a simpler architecture design.