I have written this piece of code for computing the factorial of any number that it starts to become slow when the input is about one million or higher.
How can I parallelize it to be more efficient?
I haven't studied parallelization of programs.
package programas;
import java.math.BigInteger;
import java.util.InputMismatchException;
import java.util.Scanner;
public class IterativeFactorial {
public BigInteger factorial(BigInteger n) {
if ( n == null ) {
throw new IllegalArgumentException();
}
else if ( n.signum() == - 1 ) {
// negative
throw new IllegalArgumentException("Argument must be a non-negative integer");
}
else {
BigInteger factorial = BigInteger.ONE;
for ( BigInteger i = BigInteger.ONE; i.compareTo(n) < 1; i = i.add(BigInteger.ONE) ) {
factorial = factorial.multiply(i);
}
return factorial;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
BigInteger number, result;
boolean error = false;
System.out.println("FACTORIAL OF A NUMBER");
do {
System.out.println("Enter a number:");
try {
number = scanner.nextBigInteger();
result = new IterativeFactorial().factorial(number);
error = false;
System.out.println("Factorial of " + number + ": " + result);
}
catch ( InputMismatchException e ) {
error = true;
scanner.nextLine();
}
catch ( IllegalArgumentException e ) {
error = true;
scanner.nextLine();
}
}
while ( error );
scanner.close();
}
}
You can use Stream to achieve easy parallelization of the computations by using reduction.
A reduction operation (also called a fold) takes a sequence of input elements and combines them into a single summary result by repeated application of a combining operation, such as finding the sum or maximum of a set of numbers, or accumulating elements into a list.
Above is from the package summary, take a read for more in-depth information.
BigInteger num = scanner.nextBigInteger();
BigInteger result = Stream.iterate(BigInteger.TWO, bi -> bi.compareTo(num) <= 0, bi -> bi.add(BigInteger.ONE))
.parallel()
.reduce(BigInteger.ONE, BigInteger::multiply);
System.out.println(result);
1 * 1 = 1
, no point in doing this operation.