我最近构建了一个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;
}
}
}
答案 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)