代码之家  ›  专栏  ›  技术社区  ›  Hleb

为什么使用ForkJoin框架的阶乘计算比使用递归的顺序计算慢

  •  0
  • Hleb  · 技术社区  · 7 年前

    我用两种方法实现了阶乘计算——使用递归和使用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());
        }
    }
    

    在我上次的测试中,我得到了这样的结果:

    FJP为11874865纳秒

    为什么我的FJ实现较慢,我如何改进?

    0 回复  |  直到 7 年前