【问题标题】:How can I test the speed of a String array search?如何测试字符串数组搜索的速度?
【发布时间】:2014-02-11 18:04:27
【问题描述】:

我为一个 Java 类编写了一个程序,用于在字符串数组中搜索特定目标。程序从数组的开头到数组的末尾搜索目标,然后从数组的末尾到数组的开头搜索。我应该测试两种搜索的速度,看看哪个更快。我该如何测试呢?

这是程序:

public class LinearStringSearch {

    // Array filled with random Strings
    String[] randomStrings = {"apple", "yellow", "fire", "wood", "zinc", 
            "ram", "mouse", "fish", "cheese", "dirt"};

    // Save target arguments for global access(console printing purposes)
    String target;  
    String target2; 

    /**
     * 
     * @param target - the item you want to retrieve from array
     * @param sa - the name of the array
     * @return i - the target, otherwise return error code: -1
     */
    int linearStringSearch(String target, String[] sa) {
          this.target = target;  // set class variable for print access
          for(int i = 0; i < sa.length; ++i) {
             System.out.println("Searching array position: " + i);
             if (sa[i].equals(target)) {
              // System.out.println("Target found! ");
               return i;
             }   
          }
          return -1;
    }

    /**
     * 
     * @param target - the item you want to retrieve from array
     * @param sa - the name of the array
     * @return i - the target, otherwise return error code: -1
     */
    int backwardLinearStringSearch(String target, String[] sa) {
        this.target2 = target;  // set class variable for print access
        for(int i = 9; i < sa.length; --i) {
            System.out.println("Searching array position: " + i);
            if (sa[i].equals(target)) {
                return i;
            }
        }
        return -1; // -1 means that target was not found
    }

     /*
      * The target string is searched from the beginning of the array to the end of the array, then
      * from the end of the array to the beginning of the array. 
      */
    public static void main(String[] args) {

        LinearStringSearch lss = new LinearStringSearch();

        // Search array from beginning to end
        System.out.println("Linear search: ");                          // Print title  
        int index = lss.linearStringSearch("mouse", lss.randomStrings); // Pass arguments
        System.out.println("The target " + "'" + lss.target + "'" +     // Print to console
        " found at array index: "+index);    

        // Search array from end to beginning
        System.out.println("\nBackwards linear search: ");                       // Print title
        int index2 = lss.backwardLinearStringSearch("mouse", lss.randomStrings); // Pass arguments
        System.out.println("The target " + "'" + lss.target2 + "'" +             // Print to console
        " found at array index: "+index2); 
    }   
}

这是输出:

Linear search: 
Searching array position: 0
Searching array position: 1
Searching array position: 2
Searching array position: 3
Searching array position: 4
Searching array position: 5
Searching array position: 6
The target 'mouse' found at array index: 6

Backwards linear search: 
Searching array position: 9
Searching array position: 8
Searching array position: 7
Searching array position: 6
The target 'mouse' found at array index: 6

【问题讨论】:

    标签: java


    【解决方案1】:

    JVM 非常复杂,因此如果您想获得准确和真实的结果,您必须记住 JIT 的影响。这意味着您需要测试已经通过 JIT 优化的代码,并且不会在方法计时期间更改。所以你必须写microbenchmark - 你可以使用像CaliperJMH 这样的库。在 Caliper 的这种情况下,它看起来像这样:

    public class MyBenchmark extends Benchmark {
        public void timeMyOperation(int reps) {
          for (int i = 0; i < reps; i++) {
            int index = lss.linearStringSearch("mouse", lss.randomStrings);;
          }
       }
    }
    

    【讨论】:

    • +1 适当的测试/基准测试套件通常比代码中大量开发工件更适合。
    【解决方案2】:

    看看Java Performance TestingSystem.currentTimeMillis() 或更好的 getCurrentThreadCpuTime() 是你的朋友。如果时间差太小,请考虑多次运行每个测试并比较需要多长时间。

    【讨论】:

    • 或使用System.nanoTime() 以获得更高的分辨率
    • 你错了——如果你想在必须手动实现 jvm 预热、分析 JIT 影响等时使用这样的解决方案——最后你的结果将不准确
    • +1。我建议从要测量的功能中删除 System.out.println 调用,因为这会改变执行,因此您不仅仅是测量搜索的速度。
    • 如果您正在测量经过的时间,并且希望它是正确的,则必须使用 System.nanoTime()。你不能使用 System.currentTimeMillis(),除非你不介意你的结果是错误的。 stackoverflow.com/a/13674788/516167
    • @Tobias,阅读你的附加问题的答案,他们推荐getCurrentThreadCpuTime而不是currentTimeMillis
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 2011-07-22
    • 2013-01-20
    • 2013-01-06
    • 1970-01-01
    相关资源
    最近更新 更多