import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.SwingWorker;
public class TestField {
public static void main(String[] args) {
//Storing stuff, obvious stuff
int numIterations = 5000;
double singleTimeSum = 0, multiTimeSum = 0;
//hasPrint and anything to do with it are simply a convenience thing, for print out the percentage complete every 10%
boolean hasPrint = true;
for(int i=0; i<numIterations; i++) {
//Again, these two lines are just convenience, they print out x% every 10 percent
if(!hasPrint && ((i*100)/numIterations) % 10 == 0) System.out.println((i*100)/numIterations + "%");
hasPrint = ((i*100)/numIterations) % 10 == 0;
//Run test
new Go();
try {
//We gotta hold up while our threads properly die, otherwise it makes them faster than it can destroy them,
//and computer is SAD
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Add time to sum
singleTimeSum += singleTime;
multiTimeSum += multiTime;
//and reset times
singleTime = 0;
multiTime = 0;
}
//Print out results
System.out.println("Results (across " + numIterations + " tests): ");
System.out.println("Single-Thread time:\t" + (singleTimeSum / (float)numIterations));
System.out.println("Multi-Thread time:\t" + (multiTimeSum / (float)numIterations));
}
//Go references these variables, as though "out" parameters from a class.
static double multiTime, singleTime;
//Runs the test once, stores results in multiTime, singleTime
static class Go {
public Go() {
//Fill an array of 20k random doubles, just, because.
final double[] array = new double[20000];
for (int i = 0; i < array.length; i++) array[i] = Math.random();
//The two threads store their results in here
final double[] threadTime = new double[2];
//This is the worker thread
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
double temp;
//For timing, start clock
long localTime = System.nanoTime();
//read from the array start-to-end, 6000 times
for(int readIndex = 0; readIndex < 6000; readIndex++) {
for (int i = 0; i < array.length; i++) {
temp = array[i];
}
}
//Store end time now, so that we may perform processign with this value without overhead
long endTime = System.nanoTime();
//Store in our array, without knowing which thread will end first
if(threadTime[0] < 0) threadTime[0] = (endTime - localTime)/1e6;
else threadTime[1] = (endTime - localTime)/1e6;
return null;
}
};
//This is an exact copy of the worker thread, I was unsure if just executing the SAME instance of it would execute as expected
SwingWorker<Void, Void> worker2 = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
double temp;
long localTime = System.nanoTime();
for(int readIndex = 0; readIndex < 6000; readIndex++) {
for (int i = 0; i < array.length; i++) {
temp = array[i];
}
}
long endTime = System.nanoTime();
if(threadTime[0] < 0) threadTime[0] = (endTime - localTime)/1e6;
else threadTime[1] = (endTime - localTime)/1e6;
return null;
}
};
//Thread pool
ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
//Execute each thread
pool.execute(worker);
pool.execute(worker2);
try {
//Shutdown and WAIT for our threads, so that we don't SPAM the computer with threads (it still does, anyway.)
pool.shutdown();
pool.awaitTermination(10000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Average the two Thread times.
multiTime += (threadTime[0] + threadTime[1]) / 2.0;
//Basically, run the same code on the main thread.
//Could have made another worker to just run by itself, but, meh
double temp;
long startTime = System.nanoTime();
for(int r=0; r<6000; r++) {
for (int i = 0; i < array.length; i++) {
temp = array[i];
}
}
//Store single time
singleTime += (System.nanoTime() - startTime)/1e6;
}
}
}