Дописал к моему методу ещё и вычисления при помощи fork, правда запускал не на 8 ядерном, а на 2 ядерном процессоре. И получил такие результаты.
Total 38527ms (рекурсивная реализация)
n Total 1589ms (нерекурсивная реализация)
m Total 2167ms (многопоточная нерекурсивная реализация)
f Total 2141ms (нерекурсивная реализация при помощи fork)
В моей реализации я бы не сказал что особо как то тормозит. Я даже уверен что на 8 ядерной машине будет пошустрее чем 1 поточная нерекурсивная реализация. В вашей реализации порождается уж очень большое количество обьектов, возможно это и есть причина торможения ForkJoinPool.
Исходный код
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
import test.NestedIntervals.FareyCallable.FareyForkJoinTask;
public class NestedIntervals {
private static ExecutorService executor;
private static ForkJoinPool forkPool;
private final int base;
private NestedIntervals(int base) {
this.base = base;
}
public static NestedIntervals base(int base) {
return new NestedIntervals(base);
}
public static class Fraction {
private int denominator;
private int numerator;
public Fraction(int numerator, int denominator) {
super();
this.numerator = numerator;
this.denominator = denominator;
}
public int getDenominator() {
return denominator;
}
public void setDenominator(int denominator) {
this.denominator = denominator;
}
public int getNumerator() {
return numerator;
}
public void setNumerator(int numerator) {
this.numerator = numerator;
}
@Override
public String toString() {
return numerator + "/" + denominator;
}
}
private List<Fraction> getFarey(Fraction left, Fraction right) {
Fraction mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), left.getDenominator()
+ right.getDenominator());
if (mediant.getDenominator() > base) {
return Collections.emptyList();
}
List<Fraction> result = new LinkedList<Fraction>();
result.addAll(getFarey(left, mediant));
result.add(mediant);
result.addAll(getFarey(mediant, right));
return result;
}
public List<Fraction> getFarey() {
List<Fraction> result = new LinkedList<Fraction>();
Fraction left = new Fraction(0, 1);
Fraction right = new Fraction(1, 1);
result.add(left);
result.addAll(getFarey(left, right));
result.add(right);
return result;
}
public List<Fraction> getFareyNonRecurcive() {
LinkedList<Fraction> result = new LinkedList<Fraction>();
Fraction left = new Fraction(0, 1);
Fraction right = new Fraction(1, 1);
Fraction mediant = null;
result.add(left);
result.add(right);
ListIterator<Fraction> iterator = result.listIterator();
left = iterator.next();
while (iterator.hasNext()) {
right = iterator.next();
int denominator = left.getDenominator() + right.getDenominator();
if (denominator <= base) {
mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), denominator);
iterator.previous();
iterator.add(mediant);
iterator.previous();
} else {
left = right;
}
}
return result;
}
public List<Fraction> getFareyNonRecurciveMultiThread(int threads) {
List<Fraction> result = null;
if (threads <= 1) {
result = getFareyNonRecurcive();
} else {
LinkedList<Fraction> ret = new LinkedList<Fraction>();
List<Future<LinkedList<Fraction>>> futureList = new ArrayList<Future<LinkedList<Fraction>>>();
// fill params
LinkedList<Fraction> params = fillParams(threads);
ListIterator<Fraction> listIterator = params.listIterator();
Fraction first = listIterator.next();
while (listIterator.hasNext()) {
Fraction second = (Fraction) listIterator.next();
Future<LinkedList<Fraction>> future = executor
.submit(new FareyCallable(first, second, base));
futureList.add(future);
first = second;
}
try {
for (int i = 0; i < futureList.size(); i++) {
if (i == 0) {
ret.addAll(futureList.get(i).get());
} else {
LinkedList<Fraction> linkedList = futureList.get(i)
.get();
linkedList.pollFirst();
ret.addAll(linkedList);
}
}
} catch (Exception e) {
e.printStackTrace();
}
result = ret;
}
return result;
}
public List<Fraction> getFareyNonRecurciveFork(int parts) {
List<Fraction> result = null;
if (parts <= 1) {
result = getFareyNonRecurcive();
} else {
FareyForkMapReduceTask fareyForkMapTask = new FareyForkMapReduceTask(base, parts);
result = forkPool.invoke(fareyForkMapTask);
}
return result;
}
private LinkedList<Fraction> fillParams(int parts) {
LinkedList<Fraction> params = new LinkedList<Fraction>();
params.add(new Fraction(0, 1));
params.add(new Fraction(1, 1));
Fraction left = null;
Fraction right = null;
Fraction mediant = null;
for (int j = 0; j < base; j++) {
ListIterator<Fraction> listIterator = params.listIterator();
left = listIterator.next();
while (listIterator.hasNext()) {
if (params.size() - 1 == parts) {
return params;
}
right = listIterator.next();
int denominator = left.getDenominator()
+ right.getDenominator();
if (denominator <= base) {
mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), denominator);
listIterator.previous();
listIterator.add(mediant);
left = listIterator.next();
} else {
left = right;
}
}
}
throw new RuntimeException();
}
public static class FareyCallable implements Callable<LinkedList<Fraction>> {
private Fraction first;
private Fraction last;
private int base;
public FareyCallable(Fraction first, Fraction last, int base) {
super();
this.first = first;
this.last = last;
this.base = base;
}
@Override
public LinkedList<Fraction> call() throws Exception {
LinkedList<Fraction> result = new LinkedList<Fraction>();
Fraction left = first;
Fraction right = last;
Fraction mediant = null;
result.add(left);
result.add(right);
ListIterator<Fraction> iterator = result.listIterator();
left = iterator.next();
while (iterator.hasNext()) {
right = iterator.next();
int denominator = left.getDenominator()
+ right.getDenominator();
if (denominator <= base) {
mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), denominator);
iterator.previous();
iterator.add(mediant);
iterator.previous();
} else {
left = right;
}
}
return result;
}
public static class FareyForkJoinTask extends
RecursiveTask<LinkedList<Fraction>> {
private Fraction first;
private Fraction last;
private int base;
public FareyForkJoinTask(Fraction first, Fraction last, int base) {
super();
this.first = first;
this.last = last;
this.base = base;
}
@Override
protected LinkedList<Fraction> compute() {
LinkedList<Fraction> result = new LinkedList<Fraction>();
Fraction left = first;
Fraction right = last;
Fraction mediant = null;
result.add(left);
result.add(right);
ListIterator<Fraction> iterator = result.listIterator();
left = iterator.next();
while (iterator.hasNext()) {
right = iterator.next();
int denominator = left.getDenominator()
+ right.getDenominator();
if (denominator <= base) {
mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), denominator);
iterator.previous();
iterator.add(mediant);
iterator.previous();
} else {
left = right;
}
}
return result;
}
}
}
public static class FareyForkMapReduceTask extends
RecursiveTask<LinkedList<Fraction>> {
private int base;
private int parts;
public FareyForkMapReduceTask(int base, int parts) {
super();
this.base = base;
this.parts = parts;
}
@Override
protected LinkedList<Fraction> compute() {
List<FareyForkJoinTask> taskList = map();
return reduce(taskList);
}
private LinkedList<Fraction> reduce(List<FareyForkJoinTask> taskList) {
LinkedList<Fraction> ret = new LinkedList<Fraction>();
try {
for (int i = 0; i < taskList.size(); i++) {
FareyForkJoinTask task = taskList.get(i);
task.join();
if (i == 0) {
ret.addAll(task.get());
} else {
LinkedList<Fraction> linkedList = task
.get();
linkedList.pollFirst();
ret.addAll(linkedList);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
private List<FareyForkJoinTask> map() {
List<FareyForkJoinTask> taskList = new ArrayList<FareyForkJoinTask>();
// fill params
LinkedList<Fraction> params = fillParams(parts);
ListIterator<Fraction> listIterator = params.listIterator();
Fraction first = listIterator.next();
while (listIterator.hasNext()) {
Fraction second = (Fraction) listIterator.next();
FareyForkJoinTask task = new FareyForkJoinTask(first, second, base);
taskList.add(task);
task.fork();
first = second;
}
return taskList;
}
private LinkedList<Fraction> fillParams(int parts) {
LinkedList<Fraction> params = new LinkedList<Fraction>();
params.add(new Fraction(0, 1));
params.add(new Fraction(1, 1));
Fraction left = null;
Fraction right = null;
Fraction mediant = null;
for (int j = 0; j < base; j++) {
ListIterator<Fraction> listIterator = params.listIterator();
left = listIterator.next();
while (listIterator.hasNext()) {
if (params.size() - 1 == parts) {
return params;
}
right = listIterator.next();
int denominator = left.getDenominator()
+ right.getDenominator();
if (denominator <= base) {
mediant = new Fraction(left.getNumerator()
+ right.getNumerator(), denominator);
listIterator.previous();
listIterator.add(mediant);
left = listIterator.next();
} else {
left = right;
}
}
}
throw new RuntimeException();
}
}
public static void main(String[] args) {
int threads = 2;
int parts = 1024;
int base = 5000;
executor = Executors.newFixedThreadPool(threads);
forkPool = new ForkJoinPool(threads);
long time = 0;
List<Fraction> farey = null;
for (int i = 0; i < 10; i++) {
time = System.currentTimeMillis();
farey = NestedIntervals.base(base).getFarey();
System.out.printf("Total %dms ", System.currentTimeMillis() - time);
System.out.println(farey.size());
farey = null;
System.gc();
time = System.currentTimeMillis();
farey = NestedIntervals.base(base).getFareyNonRecurcive();
System.out.printf("n Total %dms ", System.currentTimeMillis()
- time);
System.out.println(farey.size());
farey = null;
System.gc();
time = System.currentTimeMillis();
farey = NestedIntervals.base(base).getFareyNonRecurciveMultiThread(
threads);
System.out.printf("m Total %dms ", System.currentTimeMillis()
- time);
System.out.println(farey.size());
farey = null;
System.gc();
time = System.currentTimeMillis();
farey = NestedIntervals.base(base).getFareyNonRecurciveFork(parts);
System.out.printf("f Total %dms ", System.currentTimeMillis()
- time);
System.out.println(farey.size());
farey = null;
System.gc();
}
executor.shutdownNow();
forkPool.shutdownNow();
}
}
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.
Total 38527ms (рекурсивная реализация)
n Total 1589ms (нерекурсивная реализация)
m Total 2167ms (многопоточная нерекурсивная реализация)
f Total 2141ms (нерекурсивная реализация при помощи fork)
В моей реализации я бы не сказал что особо как то тормозит. Я даже уверен что на 8 ядерной машине будет пошустрее чем 1 поточная нерекурсивная реализация. В вашей реализации порождается уж очень большое количество обьектов, возможно это и есть причина торможения ForkJoinPool.