Skip to content

Instantly share code, notes, and snippets.

@Afforess
Created January 7, 2012 01:49
Show Gist options
  • Save Afforess/1573448 to your computer and use it in GitHub Desktop.
Save Afforess/1573448 to your computer and use it in GitHub Desktop.
Trove vs Java Concurrent
public class Main {
public static void main(String[] args) {
long troveGetTime, trovePutTime, javaGetTime, javaPutTime;
troveGetTime = trovePutTime = javaGetTime = javaPutTime = 0L;
for (int test = 0; test < 10; test++) {
ConcurrentHashMap<Integer, Integer> testMap = new ConcurrentHashMap<Integer, Integer>(100000);
TIntObjectMap<Integer> testMap2 = TCollections.synchronizedMap(new TIntObjectHashMap<Integer>(100000));
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
threads.add(new TroveMapThread("A", testMap2));
}
else {
threads.add(new JavaMapThread("B", testMap));
}
}
for (int i = 0; i < 10; i++) {
threads.get(i).start();
}
boolean done = false;
while (!done){
for (int i = 0; i < 10; i++) {
if (threads.get(i).isAlive()) {
try {
Thread.sleep(250);
} catch (InterruptedException e) { }
break;
}
}
done = true;
}
for (int i = 0; i < 10; i++) {
Thread t = threads.get(i);
if (t instanceof TroveMapThread) {
troveGetTime += ((TroveMapThread)t).getTime;
trovePutTime += ((TroveMapThread)t).putTime;
}
else {
javaGetTime += ((JavaMapThread)t).getTime;
javaPutTime += ((JavaMapThread)t).putTime;
}
}
}
System.out.println("Trove Map Threads completed put operations in " + (trovePutTime / 1E6D) + " ms");
System.out.println("Trove Map Threads completed get operations in " + (troveGetTime / 1E6D) + " ms");
System.out.println("Java Map Threads completed put operations in " + (javaPutTime / 1E6D) + " ms");
System.out.println("Java Map Threads completed get operations in " + (javaGetTime / 1E6D) + " ms");
}
}
class TroveMapThread extends Thread {
TIntObjectMap<Integer> map;
Random rand = new Random();
String name;
long putTime = 0L;
long getTime = 0L;
public TroveMapThread(String name, TIntObjectMap<Integer> map) {
this.map = map;
this.name = name;
}
public void run() {
long time;
time = System.nanoTime();
for (int test = 0; test < 25; test++) {
if (test % 5 == 0) {
time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
map.put(rand.nextInt(10000), rand.nextInt(10000));
}
putTime += (System.nanoTime() - time);
}
else {
time = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.get(rand.nextInt(10000));
}
getTime += (System.nanoTime() - time);
}
}
}
}
class JavaMapThread extends Thread {
Map<Integer, Integer> map;
Random rand = new Random();
String name;
long putTime = 0L;
long getTime = 0L;
public JavaMapThread(String name, Map<Integer, Integer> map) {
this.map = map;
this.name = name;
}
public void run() {
long time;
for (int test = 0; test < 25; test++) {
if (test % 5 == 0) {
time = System.nanoTime();
for (int i = 0; i < 10000; i++) {
map.put(rand.nextInt(10000), rand.nextInt(10000));
}
putTime += (System.nanoTime() - time);
}
else {
time = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
map.get(rand.nextInt(10000));
}
getTime += (System.nanoTime() - time);
}
}
}
}
@karussell
Copy link

use join not sleep :)

@Afforess
Copy link
Author

I wrote this up in a hurry. We have a much better official test based off of this now:

https://github.com/SpoutDev/SpoutAPI/blob/master/src/test/java/org/spout/api/util/map/concurrent/TSyncLongObjectHashMapTest.java

@karussell
Copy link

Cool, thanks for sharing!!

Two notes:

  1. you should warm the jvm
  2. doing perf tests in test folder is problematic (I did this one week ago too!!) as maven enables assertion!!! so if e.g. the java core devs have a lot of asserts this can change numbers a lot

@Afforess
Copy link
Author

1.) Is there a good way to do this in Maven? IIRC, this requires specific launch arguments for hotspot to not use lazy loading of classes.
2.) Er, I am no expert on tests, but I don't see any assertations for that test. Is assertation going to affect the performance of all java code?

@karussell
Copy link

Is there a good way to do this in Maven?

I just meant, you should execute the same code twice: one without measurement and less iterations (warming) and one with. You can easily see if further warming would be necessary: the identical code gets faster and faster

but I don't see any assertations for that test.

I meant assertion of the code in the used classes. (for me assert statements in the code are bad practise) but you'll have to make sure that there are no asserts in all java code critical when comparing. I checked and indeed there seem to be no assert statements in java.uti. HashMap + base class but you'll need to check this for the other class too.

@Afforess
Copy link
Author

just meant, you should execute the same code twice: one without measurement and less iterations (warming) and one with. You can easily see if further warming would be necessary: the identical code gets faster and faster

This already runs 10 tests. I guess I could make it run 11 and discard the first test results.

I meant assertion of the code in the used classes. (for me assert statements in the code are bad practise) but you'll have to make sure that there are no asserts in all java code critical when comparing. I checked and indeed there seem to be no assert statements in java.uti. HashMap + base class but you'll need to check this for the other class too.

Trove has no assertation in it either. Trove is generated by C code anyway, but jd-gui confirmed the lack of asserts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment