Skip to content

Instantly share code, notes, and snippets.

@multiplemonomials
Last active May 2, 2016 05:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save multiplemonomials/484699de060074caf30bc63367cf0f00 to your computer and use it in GitHub Desktop.
Save multiplemonomials/484699de060074caf30bc63367cf0f00 to your computer and use it in GitHub Desktop.
Java program to test whether running a long operation in one or many threads is faster.
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/**
* Calculates the Fibonacci sequence to 59 using varying numbers of threads
* @author Jamie
*
*/
public class MultithreadBenchmarker
{
public static List<Integer> results = Collections.synchronizedList(new ArrayList<Integer>());
private static class FibonacciCalcRunnable implements Runnable
{
int numThreads;
int offset;
boolean wasInterrupted = false;
/**
*
* @param numThreads how many threads there are, aka how large of an interval to skip between numbers
* @param offset how far from 0 to start finding numbers
*/
public FibonacciCalcRunnable(int numThreads, int offset)
{
super();
this.numThreads = numThreads;
this.offset = offset;
}
@Override
public void run()
{
for(int posInSequence = offset; !wasInterrupted; posInSequence += numThreads)
{
System.out.print(posInSequence + " ");
int nextNum = fibonacciNumberRecursive(posInSequence);
if(wasInterrupted)
{
//special flag to indicate that we didn't finish calculating this number
nextNum = -1;
}
if(results.size() <= posInSequence)
{
results.add(nextNum);
}
else
{
results.set(posInSequence, nextNum);
}
}
}
private int fibonacciNumberRecursive(int posInSequence)
{
if(posInSequence <= 1)
{
return posInSequence;
}
if(Thread.interrupted() || wasInterrupted)
{
wasInterrupted = true;
return -1;
}
return fibonacciNumberRecursive(posInSequence - 1) + fibonacciNumberRecursive(posInSequence - 2);
}
}
public static void main(String[] args)
{
//numbers of threads to try the calculation with
int[] numThreadsToUse = new int[]{1, 2, 4, 5, 10, 20};
for(int threadCountIndex = 0; threadCountIndex < numThreadsToUse.length; ++threadCountIndex)
{
final int numThreads = numThreadsToUse[threadCountIndex];
long startTime = System.nanoTime();
System.out.println("\n----------------------------------------------------------\n");
System.out.printf("Calculating sequence with %d thread%s...\n", numThreads, numThreads > 1 ? "s" : "");
HashSet<Thread> spawnedThreads = new HashSet<Thread>();
for(int threadIndex = 0; threadIndex < numThreads; ++threadIndex)
{
FibonacciCalcRunnable calcRunnable = new FibonacciCalcRunnable(numThreads, threadIndex);
Thread fibonacciThread = new Thread(calcRunnable);
fibonacciThread.start();
spawnedThreads.add(fibonacciThread);
}
try
{
Thread.sleep(15000);
}
catch(InterruptedException e1)
{
e1.printStackTrace();
}
for(Thread fibonacciThread : spawnedThreads)
{
try
{
fibonacciThread.interrupt();
fibonacciThread.join();
}
catch(InterruptedException e)
{
//this shouldn't ever happen, there's no one to call interrupt()
e.printStackTrace();
}
}
long endTime = System.nanoTime();
//results might have holes, so find out how many numbers are actually in it
int numbersCalculated = 0;
for(int index = 0; index < results.size(); ++index)
{
if(results.get(index) != -1)
{
++numbersCalculated;
}
}
System.out.println("\nSequence: " + results.toString());
System.out.printf("%d numbers in %.02f ms = %.02f num per second\n", numbersCalculated, (endTime - startTime) / 1e6, numbersCalculated / ((endTime - startTime) / 1e9));
}
}
}
Output on my quad-core (with hyperthreading) laptop:
----------------------------------------------------------
Calculating sequence with 1 thread...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, -1]
45 numbers in 15003.76 ms = 3.00 num per second
----------------------------------------------------------
Calculating sequence with 2 threads...
0 1 2 3 5 7 4 6 9 8 11 10 13 12 15 14 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, -1, -1]
47 numbers in 15000.57 ms = 3.13 num per second
----------------------------------------------------------
Calculating sequence with 4 threads...
0 4 8 12 1 16 5 2 6 10 9 13 3 20 7 17 14 21 24 11 18 15 25 22 19 23 28 26 27 29 30 32 31 33 34 36 35 37 38 39 40 41 42 43 44 45 46 47 48 49 50
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, -1, -1, -1]
47 numbers in 15000.28 ms = 3.13 num per second
----------------------------------------------------------
Calculating sequence with 5 threads...
0 5 10 15 1 20 6 11 2 16 25 3 21 7 8 4 9 13 12 18 26 14 23 17 19 22 24 28 27 29 30 31 32 33 34 36 35 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, -1, -1, -1, -1]
47 numbers in 15000.17 ms = 3.13 num per second
----------------------------------------------------------
Calculating sequence with 10 threads...
0 10 20 1 30 11 21 2 12 22 3 13 31 23 4 14 24 32 8 18 7 17 28 27 6 16 33 9 19 29 5 15 25 35 37 38 39 40 41 42 26 34 36 43 44 45 46 47 48 49 50 51 52 53 54 55
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, -1, -1, -1, -1, -1, -1, -1, -1, -1]
46 numbers in 15014.56 ms = 3.06 num per second
----------------------------------------------------------
Calculating sequence with 20 threads...
0 20 1 40 21 2 22 3 23 41 5 25 43 4 24 19 39 44 45 42 16 36 14 34 17 18 37 38 15 35 11 31 7 27 10 30 9 29 47 49 50 51 6 13 33 26 12 32 46 8 28 48 52 54 53 55 56 57 58 59 60 61 62 63
Sequence: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
44 numbers in 15148.58 ms = 2.90 num per second
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment