【发布时间】:2012-10-26 15:25:17
【问题描述】:
我在这里有两个不同的递归函数用于在 Java 中反转字符串:
Long ms1 = System.currentTimeMillis();
String str1 = reverse1(str);
ms1 = System.currentTimeMillis() - ms1;
Long ms2 = System.currentTimeMillis();
String str2 = reverse2(str);
ms2 = System.currentTimeMillis() - ms2;
System.out.println("Input: " + str);
System.out.println(" Length: " + str.length());
System.out.println("Reverse 1:");
System.out.println(" " + herp + " function calls");
System.out.println(" " + ms1 + " milliseconds");
System.out.println("Reverse 2:");
System.out.println(" " + derp + " function calls");
System.out.println(" " + ms2 + " milliseconds");
}
public static String reverse1(String str){
herp++;
if(str.length() == 1) return str;
return reverse1(str.substring(str.length()/2)) + reverse1(str.substring(0, str.length()/2));
}
public static String reverse2(String str){
derp++;
if(str.length() == 1) return str;
return reverse2(str.substring(1)) + str.charAt(0);
}
给定一个长度为 5000 的字符串,这是程序的输出:
Input: ...
Length: 5000
Reverse 1:
9999 function calls
16 milliseconds
Reverse 2:
5000 function calls
52 milliseconds
现在为什么具有两倍函数调用的函数要快 3 倍?我应该如何构建我的递归函数以在 Java 中实现最大速度?
【问题讨论】:
-
您确定没有除法舍入错误吗?
-
两个反向函数都正确地反转输入字符串,如果这是你的问题
-
出于好奇,您是否在进行这些测试之前预热了 JVM?虽然如果它没有预热,我预计第一次测试的时间会比第二次要慢。
-
我的猜测是,这里的大部分时间实际上都花在创建(和存储)字符串上:第一个函数更好,因为它的参数长度迅速下降(5000 - 2500 - 1250 ...),在第二个函数中是 (5000 - 4999 - 4998...)。
-
需要说明的是:在变量默认可变的语言中,递归与速度无关。这是关于简单的。如果您担心性能而不是简单性,尤其是在像 Java 这样的语言中,您应该意识到迭代解决方案几乎每次都会更快。在这种情况下,迭代
reverse()可能是 O(N)。