我在CodingBat上做这个FizzBuzz练习;
给定字符串str,如果字符串以"f"开头,则返回"Fizz"。如果字符串以"b"结尾,则返回"Buzz"。如果"f"one_answers"b"条件都成立,则返回"FizzBuzz"。在所有其他情况下,返回字符串时保持不变。
并给出了这个答案;
public String fizzString(String str)
{
String sum = "";
if (str.startsWith("f")) sum += "Fizz";
if (str.endsWith("b")) sum += "Buzz";
return (sum == "") ? str : sum;
}
然而,这个问题的作者还是选择了;
public String fizzString(String str)
{
if (str.startsWith("f") && str.endsWith("b")) return "FizzBuzz";
if (str.startsWith("f")) return "Fizz";
if (str.endsWith("b")) return "Buzz";
return str;
}
这似乎太多余了。。。
我想知道,在现实世界中,从性能角度来看,选择第一个节目而不是第二个节目会有什么不同吗?
我的计算表明情况并非如此。。。(评论区太拥挤了。)
我有一个java程序,它将在设定的时间(1000毫秒)内尽可能快地运行一块代码。它将这样做10次,以获得平均值、最小值和最大值。
我不得不说,第一种方法的速度更快,平均每秒大约有4000000个循环。
以下是我的结果:
First Method:
Least loops: 26,312,768
Most loops: 26,918,157
Average loops: 26,582,653.7
Second Method:
Least loops: 22,039,592
Most loops: 22,596,476
Average loops: 22,424,598.5
这是我的源代码,请告诉我我得到的数据可能有偏差。我保持计算机的负载不变,代码也保持不变。唯一改变的是我在while
循环中调用的内容。
package personal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SpeedTest {
public static void main(String[] args) {
int loops = 10;
double DELAY = 1000;
int i;
double[] loopCount = new double[loops + 1];
double sum = 0;
for (i = 0; i < loops + 1; i++) {
long startTime = System.currentTimeMillis();
long endTime = (long)(startTime + DELAY);
long index = 0;
while (true) {
fizzString("TEST");
//fizzString2("TEST");
long now = System.currentTimeMillis();
if (now >= endTime) {
break;
}
index++;
}
if (i != 0) {
if (DELAY != 1000) {
if (DELAY / 1000 % 1 == 0) {
System.out.printf("Test %.0f. %,.0f loops in %.0f seconds.n", (float) i, (float) index, (float) DELAY / 1000);
} else if ((DELAY / 100) % 1 == 0) {
System.out.printf("Test %.0f. %,.0f loops in %.1f seconds.n", (float) i, (float) index, (float) DELAY / 1000);
} else if ((DELAY / 10) % 1 == 0) {
System.out.printf("Test %.0f. %,.0f loops in %.2f seconds.n", (float) i, (float) index, (float) DELAY / 1000);
} else if (DELAY % 1 == 0) {
System.out.printf("Test %.0f. %,.0f loops in %.3f seconds.n", (float) i, (float) index, (float) DELAY / 1000);
}
} else {
System.out.printf("Test %.0f. %,.0f loops in %.0f second.n", (float) i, (float) index, (float) DELAY / 1000);
}
loopCount[i] = index;
}
}
Arrays.sort(loopCount);
System.out.printf("Least loops: %,.0fn", (loopCount[1]));
System.out.printf("Most loops: %,.0fn", loopCount[loops]);
for (int d = 1; d < loopCount.length; d++) {
sum += loopCount[d];
}
double averageLoopCount = 1.0f * sum / (loopCount.length - 1);
System.out.printf("Average loops: %,.1f", averageLoopCount);
}
public static String fizzString(String str) {
if (str.startsWith("f") && str.endsWith("b")) return "FizzBuzz";
if (str.startsWith("f")) return "Fizz";
if (str.endsWith("b")) return "Buzz";
return str;
}
public static String fizzString2(String str) {
String sum = "";
if (str.startsWith("f")) sum += "Fizz";
if (str.endsWith("b")) sum += "Buzz";
return (sum == "") ? str : sum;
}
}
自己试试:)
这实际上取决于实际执行的CPU指令,
但总的想法是有
- 执行的分支数最少(如果为else)
- 内存访问次数最少
- 没有动态分配
这样的解决方案应该比这两种方案都快。
public String fizzString(String str)
{
if (str.length() == 0) return str;
if (str.charAt(0) == 'f') {
if (str.charAt(str.length() - 1) == 'b') {
return "FizzBuzz";
}
return "Fizz";
}
if (str.charAt(str.length() - 1) == 'b') {
return "Buzz";
}
return str;
}