解决FizzBu​​zz的最佳性能方法

时间:2016-05-04 18:16:16

标签: java string performance

我在做this FizzBuzz exercise on CodingBat;

  

给定字符串str,如果字符串以" f"开头。返回" Fizz"。如果字符串以" b"结尾返回" Buzz"。如果两者都是" f"和" b"条件是真的,返回" FizzBu​​zz"。在所有其他情况下,返回字符串不变。

并得出了这个答案;

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;
}

然而,问题的作者去了;

if("Vani".equals(fname)) { //You can use equalsIgnoreCase instead if you like
    System.out.println("You are in.");
} else {
    System.out.println("You are out.");
}

这似乎太多余了......

我想知道,它会在现实世界中有所作为,在性能方面,是为了第一个程序而不是第二个程序?

2 个答案:

答案 0 :(得分:0)

我的计算不然......(评论部分太拥挤了。)

我有一个java程序,它将尽可能快地运行一段代码一段时间(1000毫秒)。它会做10次以获得平均值,最少值和最多值。

我得说,第一种方法更快,平均每秒约4,000,000次循环。

以下是我的结果:

   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: %,.0f\n", (loopCount[1]));
    System.out.printf("Most loops: %,.0f\n", 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;
  }
}
&#13;
&#13;
&#13;

试试自己:)

答案 1 :(得分:0)

这实际上取决于执行的实际CPU指令,

但一般的想法是

  • 执行分支的最少数量(if-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;
}