我在stackoverflow上搜索Java中的多线程factorial变体,但令我惊讶的是,没有任何。所以我想自己做,因为我希望看到性能有所提高。 (我在这里为正在搜索此内容的人分享代码。) 现在我想将其性能与单线程迭代方法和递归方法进行比较。但我没有看到任何性能提升,它的单线程对应物的价值高达1200! (长数据类型不能保持21的值!因为它大于Long.MAX_VALUE。)那么如何使用更大的数字进行比较?我正在使用BigInteger和1232!是两种方法得到的最大值。
import java.math.BigInteger;
import java.util.Arrays;
public class MultiThreadedFactorial
{
public static void main(String[] args) throws InterruptedException
{
long startTime=System.nanoTime();
int x=1232;
if(x<2) return;
int[] array=new int[x-1];//It is x-1 because of 1 is not included in 2...10.
for(int i=0;i<array.length;i++)
{
array[i]=i+2;
}
int[] partA=Arrays.copyOfRange(array,0,array.length/3);//Dividing array into 3 equal parts
PartialProduct A=new PartialProduct(partA);
int[] partB=Arrays.copyOfRange(array,array.length/3,2*array.length/3);
PartialProduct B=new PartialProduct(partB);
int[] partC=Arrays.copyOfRange(array,2*array.length/3,array.length);
PartialProduct C=new PartialProduct(partC);
A.start();
B.start();
C.start();
A.join();
B.join();
C.join();
BigInteger bi=new BigInteger(A.product+"");
bi=bi.multiply(new BigInteger(B.product+""));
bi=bi.multiply(new BigInteger(C.product+""));
System.out.println(bi.toString());
long endTime=System.nanoTime();
float totalTime=(endTime-startTime)/1000000000f;
System.out.println("Took "+totalTime+" seconds!");
}
static long multiply(long... numbers)
{
long factorial=1;
for(long n:numbers)
factorial*=n;
return factorial;
}
}
class PartialProduct extends Thread
{
int[] numbers;
BigInteger product=new BigInteger("1");
public PartialProduct(int[] numbers)
{
this.numbers=numbers;
}
public void run()
{
for(int n:numbers)
product=product.multiply(BigInteger.valueOf(n));
}
}
答案 0 :(得分:1)
使用Java 8中提供的Java流API编写factorial的并行版本要容易得多。
单线程实现可能如下所示:
static BigInteger sequentialFactorial(int n)
{
if (n < 2)
return BigInteger.ONE;
return IntStream.rangeClosed(2, n)
.sequential()
.mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ONE, BigInteger::multiply, BigInteger::multiply);
}
并行/多线程版本是一个微不足道的变化:
static BigInteger parallelFactorial(int n)
{
if (n < 2)
return BigInteger.ONE;
return IntStream.rangeClosed(2, n)
.parallel()
.mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ONE, BigInteger::multiply, BigInteger::multiply);
}
如果你以明智的方式计算时间(例如,1000次迭代,每次计算1000次!),你应该会在多核机器上看到显着的加速。