为什么我的java程序逐渐变慢?

时间:2017-11-08 16:37:15

标签: java time-complexity fibonacci

我最近构建了一个Fibonacci生成器,它使用递归和散列映射来降低复杂性。我使用System.nanoTime()来跟踪我的程序打印10000个Fibonacci数所需的时间。它开始时间不到一秒,但逐渐变慢,现在需要超过4秒。有人可以解释为什么会发生这种情况。代码在这里 -

import java.util.*;
import java.math.*;

public class FibonacciGeneratorUnlimited {

    static int numFibCalls = 0;
    static HashMap<Integer, BigInteger> d = new HashMap<Integer, BigInteger>();
    static Scanner fibNumber = new Scanner(System.in);
    static BigInteger ans = new BigInteger("0");

    public static void main(String[] args){
        d.put(0 , new BigInteger("0")); 
        d.put(1 , new BigInteger("1"));

        System.out.print("Enter the term:\t");
        int n = fibNumber.nextInt();

        long startTime = System.nanoTime();

        for (int i = 0; i <= n; i++) {
            System.out.println(i + " : " + fib_efficient(i, d));
        }

        System.out.println((double)(System.nanoTime() - startTime) / 1000000000);
    }
    public static BigInteger fib_efficient(int n, HashMap<Integer, BigInteger> d) {
        numFibCalls += 1;
        if (d.containsKey(n)) {
            return (d.get(n));
        } else {
            ans = (fib_efficient(n-1, d).add(fib_efficient(n-2, d)));
            d.put(n, ans);
            return ans;
        }
    }
}

4 个答案:

答案 0 :(得分:0)

如果您每次制作新的斐波纳契序列时重新启动程序,那么您的程序很可能不是问题所在。可能只是您的处理器在运行程序几次后变热,或者计算机中的后台进程突然启动,导致程序速度变慢。

答案 1 :(得分:0)

更多内存java -Xmx=...或更少缓存

public static BigInteger fib_efficient(int n, HashMap<Integer, BigInteger> d) {
    numFibCalls++;
    if ((n & 3) <= 1) { // Every second is cached.
        BigInteger cached = d.get(n);
        if (cached != null) {
            return cached;
        } else {
            BigInteger ans = fib_efficient(n-1, d).add(fib_efficient(n-2, d));
            d.put(n, ans);
            return ans;
        }
    } else {
        return fib_efficient(n-1, d).add(fib_efficient(n-2, d));
    }
}

为了阻止两个后续的数字,从四个中缓存出来 两个分支上的递归:

fib(n) = fib(n-1) + fib(n-2)

BigInteger并不是性能和内存最好的类。

答案 2 :(得分:0)

  

它在不到一秒的时间内开始变好,但逐渐变慢,现在需要超过4秒。

这是什么意思?你的意思是你使用相同的输入运行这个完全相同的程序,其运行时间从&lt; 1秒钟> 1秒4秒? 如果您在确定性算法中使用相同的确切输入运行相同的确切代码... 然后差异可能在您的代码外部 - 也许其他进程在一次运行中占用更多CPU。 你的意思是你将输入从某个值X增加到10,000,现在它需要&gt; 4秒? 然后,只需要算法在较大输入时花费更长时间,这是完全正常的。

  

递归和散列图以降低复杂性

并不是复杂程度如何。你已经改进了最佳案例和平均案例,但你没有做任何改变最坏情况的事情。

  

现在提供一些实际的绩效改进建议

停止打印结果 ...占用了超过99%的处理时间。但是,严肃地说,切换出&#34; System.out.println(i +&#34;:&#34; + fib_efficient(i,d))&#34;用&#34; fib_efficient(i,d)&#34;并且它的执行速度会快100倍。 连接字符串和打印到控制台是非常昂贵的过程。

答案 3 :(得分:0)

这是因为Fibonacci的复杂性是 Big-O(n ^ 2) 。这意味着,输入越大,时间就会呈指数级增长,正如您在此link中的 Big-O(n ^ 2) 图表中所示。请查看此answer以查看有关其复杂性的完整说明。

现在,算法的复杂性增加了,因为每次调用该函数时都使用HashMap来搜索和插入元素。请考虑删除此HashMap