问题
I am trying to transform each element of an array of length 10,00,00,000. My first approach is using a single thread in a simple main method. My next approach is using fork-join framework of java by dividing the array into chunks of 10,00,000. But the total time taken to transform the array is almost same in both the approaches.
public class SerialComputation {
public static void main(String[] args) {
Integer[] array = new Integer[100000000];
for (int i = 0; i < array.length; i++) {
array[i] = new Random().nextInt(100);
}
System.out.println("First 10 elements before transformation:");
Arrays.asList(array).stream().limit(10).forEach(d -> System.out.print(d + " "));
System.out.println();
long startTime = System.currentTimeMillis();
for (int i = 0; i < array.length; i++) {
array[i] *= 2;
}
long endTime = System.currentTimeMillis();
System.out.println("First 10 elements after transformation:");
Arrays.asList(array).stream().limit(10).forEach(d -> System.out.print(d + " "));
System.out.println();
System.out.println("Total time taken: " + (endTime - startTime));
}
}
class ParallelComputation {
public static void main(String[] args) {
Integer[] array = new Integer[100000000];
for (int i = 0; i < array.length; i++) {
array[i] = new Random().nextInt(100);
}
System.out.println("First 10 elements before transformation:");
Arrays.asList(array).stream().limit(10).forEach(d -> System.out.print(d + " "));
System.out.println();
ForkJoinTask<?> forkJoinTask = new TransformTask(0, array.length, array);
ForkJoinPool pool = new ForkJoinPool();
long startTime = System.currentTimeMillis();
pool.invoke(forkJoinTask);
long endTime = System.currentTimeMillis();
System.out.println("First 10 elements after transformation:");
Arrays.asList(array).stream().limit(10).forEach(d -> System.out.print(d + " "));
System.out.println("Total time taken: " + (endTime - startTime));
}
}
class TransformTask extends RecursiveAction {
private static final long serialVersionUID = 1L;
private int start;
private int end;
private Integer[] array;
public TransformTask(int start, int end, Integer[] array) {
this.start = start;
this.end = end;
this.array = array;
}
@Override
protected void compute() {
if (end - start <= 1000000) {
for (int i = start; i < end; i++) {
array[i] *= 2;
}
} else {
int middle = start + ((end - start) / 2);
System.out.println("start:" + start + "middle:" + middle + "end:" + end);
invokeAll(new TransformTask(start, middle, array), new TransformTask(middle, end, array));
}
}
}
I am expecting the ParallelComputation to calculate the result much quicker than the SerialComputation. But both are doing the job in almost same time. I am using a machine with Intel core i7 processor with windows 10.
回答1:
I can't comment on TransformTask
implementation, but this :
static long parallelStreamComputation() {
Integer[] array = new Integer[100000000];
for (int i = 0; i < array.length; i++) {
array[i] = new Random().nextInt(100);
}
long startTime = System.currentTimeMillis();
Arrays.stream(array).parallel().mapToInt( i -> i*2).toArray();
long endTime = System.currentTimeMillis();
return endTime-startTime;
}
Was measured to be about 10 times faster.
来源:https://stackoverflow.com/questions/53923815/executing-a-long-running-task-using-fork-join-taking-almost-same-time-as-single