나는 나누기와 정복 전략을 통해 Factorial 함수를 구현하려고합니다. 계산 속도를 높이기 위해 ForkJoin 프레임 워크를 사용하여 각 재귀 작업을 포크 화했습니다. 하지만 예상대로 속도가 올라가지 않는 것으로 나타났습니다. ForkJoin을 사용하지 않고 계승을 계산하는 데 28 초가 걸리는 반면, 은 ForkJoin을 사용할 때 25 초가 걸렸습니다. 이 forkjoin없이 코드 :DnC를 통한 계승 계산
public static BigInteger factorial(long p, long q) {
if (q < p) {
return new BigInteger("1");
}
if (p == q) {
return new BigInteger("" + p);
}
BigInteger fact = new BigInteger("1");
fact = fact.multiply(factorial(p, (p + q)/2)).multiply(factorial((p + q)/2 + 1, q));
return fact;
}
는 그리고이 forkJoin에 코드입니다 :
public class Factorial extends RecursiveTask<BigInteger>{
private long p, q;
public Factorial(long p, long q) {
this.p = p;
this.q = q;
}
@Override
public BigInteger compute() {
if(q < p) {
return new BigInteger("1");
}
if(p == q) {
return new BigInteger(""+p);
}
Factorial f1 = new Factorial(p, (p+q)/2);
Factorial f2 = new Factorial((p+q)/2 + 1, q);
f2.fork();
return f1.compute().multiply(f2.join());
}
}
내가 잘못 갈거야? 나는 이것이 Fork/Join의 결과라고 생각하지 않는다. 도와주세요!
계승을 많이 계산해야하는 경우 사전에 필요한 계승을 계 산한 다음 다시 계승해야합니다. 효율적인 방법으로 동시에 계승 계산을 동시에 수행 할 수는 없습니다. –
BigInteger 사용에 관한 성능 팁 :'new BigInteger ("1")'을 상수'BigInteger.ONE'으로 대체하십시오. 'new BigInteger (""+ p)'를'BigInteger.valueOf (p)'로 대체하십시오. 이것은 더 빠르며 가능한 경우 이전에 생성 된 인스턴스를 재사용합니다. – gb96
@ Maurício 큰 값의 n의 경우, 병렬 알고리즘으로 n! 이제는 가장 빠른 것으로 알려져 있습니다. http://www.luschny.de/math/factorial/FastFactorialFunctions.htm에서 알고리즘 및 벤치 마크를 참조하십시오. – gb96