I was recently doing some java performance testing when I ran this test and was absolutely shocked. I wanted to test and see what kind of performance difference I would get by doing statistics in worker group threads... that is when I got this really surprising results.
Here goes the code of the test:
import org.joda.time.DateTime;
import org.joda.time.Interval;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;
/**
* Created by siraj on 1/2/16.
*/
public class WorkerPoolTest {
int SAMPLE_LIMIT = 1000;
DecimalFormat df = new DecimalFormat("#.####");
public static void main(String[] args){
int nTestElements = 100000;
System.out.println("\tLinear\t\t\tNon-Linear");
for (int i = 0;i<25;i++){
// System.out.println("Linear test " + (i+1));
System.out.print((i + 1));
new WorkerPoolTest(false, nTestElements, false);
// System.out.println("Non-linear test " + (i+1));
new WorkerPoolTest(true, nTestElements, false);
System.out.println();
}
System.out.println("Done test");
}
WorkerPoolTest(boolean useWorkerThreads, int testLimit, boolean outPutSampleResults){
DateTime start = new DateTime();
// System.out.println(start);
startWorkerThreads(useWorkerThreads, testLimit, outPutSampleResults);
DateTime end = new DateTime();
// System.out.println(end);
System.out.print("\t " +
df.format( ((double) (new Interval(start, end).toDurationMillis()) /1000) ) + "\t\t");
}
private void startWorkerThreads(boolean userWorkerThreads, int testLimit, boolean outPutSampleResults){
ArrayList<WDataObject> data = new ArrayList<>();
if (userWorkerThreads){
try {
// do fast test
ExecutorService pool = Executors.newFixedThreadPool(6);
int nSeries = 2;
Set<Future<WDataObject>> set = new HashSet<>();
for (int i = 1; i <= testLimit; i ++){
Callable worker = new Worker(i);
Future<WDataObject> future = pool.submit(worker);
set.add(future);
}
for (Future<WDataObject> wdo : set){
data.add(wdo.get());
}
Collections.sort(data);
if (outPutSampleResults)
for (WDataObject ob: data)
{
System.out.println(ob.toString());
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}else{
// do linear test.
for (int i = 1; i <= testLimit; i ++){
WDataObject ob = new WDataObject(i);
for (int s = 1; s <= SAMPLE_LIMIT; s++){
ob.dataList.add((double)i / (double)s);
}
data.add(ob);
}
if (outPutSampleResults)
for (WDataObject ob: data)
{
System.out.println(ob.toString());
}
}
}
class Worker implements Callable{
int i;
Worker(int i){
this.i = i;
}
@Override
public WDataObject call() throws Exception {
WDataObject ob = new WDataObject(i);
for (int s = 1; s <= SAMPLE_LIMIT; s++){
ob.dataList.add((double)i / (double)s);
}
return ob;
}
}
class WDataObject implements Comparable<WDataObject>{
private final int id;
WDataObject(int id){
this.id = id;
}
ArrayList<Double> dataList = new ArrayList<>();
public Integer getID(){
return id;
}
public int getId(){
return id;
}
public String toString(){
String result = "";
for (double data: dataList) {
result += df.format(data) + ",";
}
return result.substring(0, result.length()-1);
}
@Override
public int compareTo(WDataObject o) {
return getID().compareTo(o.getID());
}
}
}
And here goes a sample of the output of running this program...
Linear | Non-Linear
1 45.735 | 15.043
2 24.732 | 16.559
3 15.666 | 17.553
4 18.068 | 17.154
5 16.446 | 19.036
6 17.912 | 18.051
7 16.093 | 17.618
8 13.185 | 17.2
9 19.961 | 26.235
10 16.809 | 17.815
11 15.809 | 18.098
12 18.45 | 19.265
How could this be when the linear calculation model is using a single thread? Also, I ran this test and watched my system monitor and noticed that while running the single embedded loop that all of my computers cores where being used at maximum strength. What's going on here? Why is it that the linear calculation algorithm gets faster with subsequent iterations and why does it sometimes out preform the threaded nonlinear version of the same job?
This code sample uses Joda Time for time stamping.
Also, I am having a hard time putting tab spaces in with this editor, the results used tab spaces. You can see it in the code.