So I am trying to understand how Java ForkJoin framework works. The simplest thing I could think of implementing was an array sum. However my parallel implementation is 3-4 times slower than the serial implementation. I must obviously be doing something wrong, but I am not sure what.
To measure the performance, I created a set of classes and interfaces (I used Lombok annotations for generating boilerplate code).
interface Result<T> {
T getValue();
}
#AllArgsConstructor(staticName = "of")
#Value
class MeasuredResult<T> implements Result<T> {
T value;
long elapsedTimeMillis;
}
#AllArgsConstructor(staticName = "of")
class CombinedResult<T> implements Result<T> {
private final MeasuredResult<T> parallelResult;
private final MeasuredResult<T> serialResult;
public double getParallelizationFactor() {
return (double) serialResult.getElapsedTimeMillis() / parallelResult.getElapsedTimeMillis();
}
public T getParallelValue() {
return parallelResult.getValue();
}
public T getSerialValue() {
return parallelResult.getValue();
}
#Override
public T getValue() {
return getSerialValue();
}
public boolean isDifferent() {
return !isSame();
}
public boolean isSame() {
return parallelResult.getValue().equals(serialResult.getValue());
}
}
interface Parallelizable<T> {
T processParallelly();
T processSerially();
default CombinedResult<T> getResult() {
MeasuredResult<T> parallelResult = measureParallel();
MeasuredResult<T> serialResult = measureSerial();
return CombinedResult.of(parallelResult, serialResult);
}
default MeasuredResult<T> measure(Supplier<T> supplier) {
long startTime = System.currentTimeMillis();
T value = supplier.get();
long endTime = System.currentTimeMillis();
return MeasuredResult.of(value, endTime - startTime);
}
default MeasuredResult<T> measureParallel() {
return measure(this::processParallelly);
}
default MeasuredResult<T> measureSerial() {
return measure(this::processSerially);
}
}
The idea was that by implementing the Parallelizable interface, I'd define the serial and parallel versions of the code and use the getResult() function to get a CombinedResult object with the values and time measurement to unit test with. Here's my implementation of the array sum.
#AllArgsConstructor
public class ArraySum implements Parallelizable<Integer> {
private final int[] nums;
#Override
public Integer processParallelly() {
return new ParallelForkJoinImpl(0, nums.length).compute();
}
#Override
public Integer processSerially() {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}
#AllArgsConstructor()
private class ParallelForkJoinImpl extends RecursiveTask<Integer> {
private static final int THRESHOLD = 1_000;
private final int start;
private final int end;
#Override
protected Integer compute() {
if (end - start <= THRESHOLD) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += nums[i];
}
return sum;
}
int mid = (start + end) / 2;
ForkJoinTask<Integer> left = new ParallelForkJoinImpl(start, mid).fork();
ForkJoinTask<Integer> right = new ParallelForkJoinImpl(mid, end).fork();
return left.join() + right.join();
}
}
}
From what I understand, calling fork() on the RecursiveTask implementation should give me a Future object as response which will block on computation when the join() function is called on it. Also use the common ForkJoinPool will automatically be used when fork() is called.
But like I said, the value for elapsedTimeMillis for the parallel implementation is 3-4 times larger than the serial implementation, and I don't know why. What did I do wrong here?
Related
this is the qa:
Define a class called MoreSpeed which extends the following class, and which provides a new method called incSpeed() which adds 1 to the inherited variable length.
this is my answer:
public class Speed {
private int length = 0;
public int getSpeed () { return length; }
public void setSpeed (int i) {
if (i > 0) {
length = i;
}
}
}
public class MoreSpeed extends Speed {
private int length;
public int incSpeed() {
return length+1;
}}
its says that the syntax is good but the class operation is wrong.
please help me,thanks.
No. You are shadowing the length from Speed. Instead, implement incSpeed with getSpeed() like
public int incSpeed() {
return getSpeed() + 1;
}
If you are supposed to modify it as well then use setSpeed(int) to do so
public int incSpeed() {
int s = getSpeed() + 1;
setSpeed(s);
return s;
}
I have made a Selector concrete class with the code implementation placed inside it, the class extends from an abstract class and implements abstract methods.
public class Selector extends ASelector {
int max;
int min;
#Override
public void selectorRange(int min, int max) {
this.min = min;
this.max = max;
}
#Override
public int selectorValue() {
Random r = new Random();
int randomNumber = r.nextInt(this.max - this.min) + min;
return randomNumber;
}
}
I have been asked to write a test harness to ensure the class is working. There is a template laid out like so:
public void run() {
StdOut.println("DSA Coursework started\n");
doPart1();
doPart2();
doPart3();
doPart4();
doPart5();
StdOut.println("\nDSA Coursework completed");
}
private void doPart1() {
StdOut.println("Part1 started\n");
// Write test harness here
StdOut.println("\nPart1 completed");
StdOut.println("==============================================\n");
}
I'm unsure as to how I would go about testing the class. What code do I need to write?
I would assume you are supposed to test that the only method your class has returns the expected result? So you could start by doing something like this:
// Write test harness here
int min = 1;
int max = 10;
Selector selector = new Selector(min, max);
assert selector.selectorValue() >= min && selector.selectorValue() < max
I am trying to write a generic heap class.
import java.util.ArrayList;
public class heap<T extends Comparable<T>>
{
private ArrayList<T> h;
private int size;
public heap()
{
h = new ArrayList<T>();
h.add(null);
size = 0;
}
public T getMin()
{
return h.get(1);
}
public T popMin()
{
T tmp = getMin();
h.set(1, h.get(size));
size--;
sift(1);
return tmp;
}
public void insert(T key)
{
h.add(key);
percolate(++size);
}
public int getSize()
{
return this.size;
}
private int getLeftSon(int i)
{
return (i<<1<=size)? i<<1 : 0;
}
private int getRightSon(int i)
{
return ((i<<1)+1<=size)? (i<<1)+1 : 0;
}
private int getFather(int i)
{
return ((i>>1)!=0)? i>>1 : 0;
}
private void swap(int i, int j)
{
T tmp = h.get(i);
h.set(i, h.get(j));
h.set(j, tmp);
}
private void sift(int i)
{
int son;
do {
son = 0;
if (getLeftSon(i) != 0)
{
son = getLeftSon(i);
if (getRightSon(i) != 0 && h.get(getRightSon(i)).compareTo(h.get(getLeftSon(i))) > 0)
son = getRightSon(i);
if (h.get(son).compareTo(h.get(i)) <= 0)
son = 0;
}
if (son!=0) {
swap(i, son);
i = son;
}
} while (son!=0);
}
private void percolate(int i)
{
T key = h.get(i);
while ((i > 1) && (key.compareTo(h.get(getFather(i))) > 0))
{
h.set(i, h.get(getFather(i)));
i = getFather(i);
}
h.set(i, key);
}
}
All good. It works like a charm. Excepting one thing: if I work with Integers I don't have 'access' to the method compareTo from Integer. meaning that I can not override it's behaviour. I will always have a Max heap this way. Can Integer compareTo by override (I don't think it can)?
So what can I do apart from creating another class MyInteger extends Integer{...} and override it there.
You could make your heap accept a Comparator in constructor and then provide a Comparator that reverses the order.
That's what the Comparator is for actually - defining an ordering that's not a natural one for the given class, being able to define multiple orderings of the same class, or indeed defining an ordering for a class you cannot modify.
The approach of accepting a comparator at construction time can be seen in TreeSet for example.
Example code stub:
public class Heap<T> { /* no need for items to extend Comparable anymore */
private final Comparator<T> cmp;
public Heap(Comparator<T> cmp) {
this.cmp = cmp;
...
}
...
}
... and then use cmp.compare(item1, item2) wherever you now use item2.compareTo(item2).
I tried looking up tutorials and videos and I understand what implementing does, although I'm a bit confused as to how one would implement a class from the Java Library. In my homework, I'm suppose to utilize the class, DataSet and make it so it accepts Comparable objects. The program is suppose to record the Min and Max values depending on the objects, in this case, I'm suppose to use strings. I wasn't sure if I needed any classes to implement the Comparable interface, so I made two classes just in case I was suppose to do so. My real question is how do I actually incorperate a String variable in the tester class to actually read and compare the object to another? thanks in advance.
public class Word implements Comparable
{
private String str;
public Word()
{
str = null;
}
public Word(String s)
{
str = s;
}
public int compareTo(Object other)
{
String n = (String) other;
return str.compareTo(n);
}
}
I wasn't sure which of the two classes would be suitable for implementing Although i think the String class below would not work at all b/c It's already a standard class so I wasn't too sure about using it
public class String implements Comparable
{
public String s;
public String()
{
s = null;
}
public String(String str)
{
s = str;
}
public int compareTo(Object other)
{
String n = (String) other;
return s.compareTo(n);
}
}
public interface Comparable
{
public int compareTo(Object other);
}
public class DataSet
{
private Object maximum;
private Object least;
private Comparable compare;
private int count;
public DataSet(Comparable s)
{
compare = s;
}
public void add(Object x)
{
if(count == 0)
least = x;
if(count == 0 || compare.compareTo(x) >=0)
maximum = x;
else if(compare.compareTo(x) <0)
least = x;
count++;
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
public class DataSetTester
{
public static void main(String[] args)
{
Comparable n = new Word("sand");
DataSet data = new DataSet(n);
data.add(new Word(man));
System.out.println("Maximum Word: " + data.getMaximum());
System.out.println("Least Word: " + data.getLeast());
}
}
An interface is a contract that showes that your class contain all methodes that are implemented in the interface. In this case the CompareTo(object other). The String class already implements the comparable interface so you don't need youre own class. I think your data set class should look something like this :
public class DataSet<T implements Comparable>
{
private T maximum;
private T least;
private T count;
public void add(T x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public T getMaximum()
{
return maximum;
}
public T getLeast()
{
return least;
}
}
T is a generic type and in your case it should be String, Here is how you create a new Data set:
DataSet<String> ds = new DataSet<String>;
I have the following code for sorting. Can this be improved?
import java.util.*;
class Church {
private String name;
private String pastor;
public Church(String name, String pastor) {
this.name = name;
this.pastor = pastor;
}
public String getPastor() {
return pastor;
}
public String getName() {
return name;
}
public void setPastor(String pastor) {
this.pastor = pastor;
}
public String toString() {
return getName() + " is Pastored by "+getPastor();
}
public int compareByPastor(Church c) {
int x = pastor.compareTo(c.getPastor());
return x;
}
public int compareByName(Church c) {
int x = name.compareTo(c.getName());
return x;
}
}
class Churches {
private final List<Church> churches;
public Churches() {
churches = new ArrayList<Church>();
}
public void addWithoutSorting(Church c) {
churches.add(c);
}
//You could always add using this method
public void addWithSorting(Church c) {
}
public void display() {
for(int j = 0; j < churches.size(); j++) {
System.out.print(churches.get(j).toString());
System.out.println("");
}
}
public List<Church> getChurches() {
return churches;
}
public void sortBy(String s) {
for (int i = 1; i < churches.size(); i++) {
int j;
Church val = churches.get(i);
for (j = i-1; j > -1; j--) {
Church temp = churches.get(j);
if(s.equals("Pastor")) {
if (temp.compareByPastor(val) <= 0) {
break;
}
}
else if(s.equals("Name")) {
if (temp.compareByName(val) <= 0) {
break;
}
}
churches.set(j+1, temp);
}
churches.set(j+1, val);
}
}
public static void main(String[] args) {
Churches baptists = new Churches();
baptists.addWithoutSorting(new Church("Pac", "Pastor G"));
baptists.addWithoutSorting(new Church("New Life", "Tudor"));
baptists.addWithoutSorting(new Church("My Church", "r035198x"));
baptists.addWithoutSorting(new Church("AFM", "Cathy"));
System.out.println("**********************Before Sorting***********************");
baptists.display();
baptists.sortBy("Pastor");
System.out.println("**********************After sorting by Pastor**************");
baptists.display();
baptists.sortBy("Name");
System.out.println("**********************After sorting by Name****************");
baptists.display();
}
}
Take a look at Collections.sort(list, comparator)
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html
class Churches
{
public void sortBy(String attribute)
{
Comparator<Church> c = null;
if ("Name".equals(attribute)) c = new ChurchNameComparator();
else if ("Pastor".equals(attribute)) c = new ChurchNameComparator();
else System.out.println("unexpected sort attribute : '" + attribute + "'");
if (c != null) Collections.sort(churches, c);
}
private static final class ChurchNameComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getName().compareTo(c2.getName());
}
}
private static final class ChurchPastorComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getPastor().compareTo(c2.getPastor());
}
}
}
The real answer here is pretty much in line with iluxa's: you want to implement a Comparator interface on your Church objects (sample code here, though you'll want to decide what constitutes greater than/less than for a church...), and then you can use Collections.sort() to sort them. That will get the job done, at the end of the day.
Of course, you just asked for advice about sorting on Stack Overflow, so I feel compelled to ask you if you need an in-place sort, what kind of Big-O performance you're looking for, and then ask you to choose between Quicksort, IntroSort, HeapSort, MergeSort, and StoogeSort for what will work best for you.
For kicks, I once coded up a few sorts in Java:
This one forces Quicksort into quadratic time, which was harder to do than I'd originally assumed,
This one shows how to implement MergeSort,
and this one demonstrates a HeapSort
I did these for my own enjoyment and education. As a general rule, you want to stick with the standard library for these sorts of things.