Я реализовал факториальный расчет двумя способами - с помощью рекурсии и с помощью фреймворка ForkJoin.Я ожидал, что реализация ForkJoin будет быстрее, но во всех случаях, когда я пытался протестировать, это всегда было медленнее (я пытался вычислять факториал для разных чисел, а также пытался настроить уровень параллелизма).Вот обе мои реализации - без FJ:
public class SequentialFactorial {
public static void main(String[] args) {
long start = System.nanoTime();
System.out.println(calculateFactorial(BigInteger.valueOf(500)));
long end = System.nanoTime();
System.out.println((end - start) + " nanoseconds for sequential");
}
private static BigInteger calculateFactorial(BigInteger n) {
if (n.compareTo(BigInteger.valueOf(2)) <= 0) {
return n;
}
return n.multiply(calculateFactorial(n.subtract(BigInteger.ONE)));
}
}
И с этим:
public class ForkJoinFactorial {
public static void main( String[] args ) {
ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
long start = System.nanoTime();
System.out.println(forkJoinPool.invoke(new FactorialTask(BigInteger.valueOf(500))));
long end = System.nanoTime();
System.out.println((end - start) + " nanoseconds for FJP");
}
}
public class FactorialTask extends RecursiveTask<BigInteger> {
private BigInteger number;
public FactorialTask(BigInteger number) {
this.number = number;
}
@Override
protected BigInteger compute() {
if (number.compareTo(BigInteger.valueOf(1)) <= 0) {
return MathUtil.calculateFactorial(number);
}
FactorialTask subtask = new FactorialTask(number.subtract(BigInteger.ONE));
subtask.fork();
return number.multiply(subtask.join());
}
}
В моих последних тестах я получил такие результаты:
5424981наносекунды для последовательных
11874865 наносекунд для FJP
Почему моя реализация FJ медленнее и как я могу это улучшить?