【问题标题】:Empirical analysis for binary search not matching Theoretical Analysis二分搜索的经验分析与理论分析不匹配
【发布时间】:2016-03-14 02:21:21
【问题描述】:

我目前正在对二进制搜索平均情况进行测试。我所做的只是生成一个随机变量,然后使用二进制搜索在不同大小的数组中搜索这个随机变量。以下是我使用的代码:

   public static void main(String[] args) 
    {
        //This array keeps track of the times of the linear search
        long[] ArrayTimeTaken = new long[18];

        //Values of the array lengths that we test for
        int[] ArrayAssignValues = new int[18];
        ArrayAssignValues[0] = 1000000;
        ArrayAssignValues[1] = 10000000;
        ArrayAssignValues[2] = 20000000;
        ArrayAssignValues[3] = 30000000;
        ArrayAssignValues[4] = 40000000;
        ArrayAssignValues[5] = 50000000;
        ArrayAssignValues[6] = 60000000;
        ArrayAssignValues[7] = 70000000;
        ArrayAssignValues[8] = 80000000;
        ArrayAssignValues[9] = 90000000;
        ArrayAssignValues[10] = 100000000;
        ArrayAssignValues[11] = 110000000;
        ArrayAssignValues[12] = 120000000;
        ArrayAssignValues[13] = 130000000;
        ArrayAssignValues[14] = 140000000;
        ArrayAssignValues[15] = 150000000;
        ArrayAssignValues[16] = 160000000;
        ArrayAssignValues[17] = 170000000;

        //Code that runs the linear search
        for (int i = 0; i < ArrayAssignValues.length; i++) 
        {
            float[] arrayExperimentTest = new float[ ArrayAssignValues[i]];

            //We fill the array with ascending numbers 
            for (int j = 0; j < arrayExperimentTest.length; j++) 
            {
                arrayExperimentTest[j] = j;
            }

            Random Generator = new Random();
            int ValuetoSearchfor = (int) Generator.nextInt(ArrayAssignValues[i]);
            System.out.println(ValuetoSearchfor);
            ValuetoSearchfor = (int) arrayExperimentTest[ValuetoSearchfor];

            //Here we perform a the Linear Search
            ArrayTimeTaken[i] = BinarySearch(arrayExperimentTest,ValuetoSearchfor);
        }
        ChartCreate(ArrayTimeTaken);  
        System.out.println("Done");
    }

这是我的二进制搜索代码:

 static long BinarySearch(float[] ArraySearch,int ValueFind)
    {
        System.gc();
        long startTime = System.nanoTime();

        int low = 0;
        int high = ArraySearch.length-1;
        int mid = Math.round((low+high)/2);

        while (ArraySearch[mid] != ValueFind ) 
        {            
            if (ValueFind <ArraySearch[mid]) 
            {
                high = mid-1;
            }
            else
            {
                low = mid+1;
            }
            mid = (low+high)/2;
        }
        long TimeTaken = System.nanoTime() - startTime;
        return TimeTaken;
    }

现在的问题是结果没有意义。下面是一张图:

有人能解释一下第一个数组是如何花费这么多时间的吗?我已经多次运行代码,每次创建的图表基本相同。 Java有的怎么缓存结果?任何人都可以解释为什么第一次二进制搜索相对于其他搜索需要这么长时间,即使数组大小与其他搜索相比很小?

【问题讨论】:

  • 可能算法正在运行,而部分 JVM 正在加载? JVM 确实在幕后做了一些惰性初始化。

标签: java computation-theory


【解决方案1】:

您似乎是在依次进行这些搜索,从最低值开始。如果这是真的,那么代码将运行得更慢,因为 JIT 编译器还没有机会预热。通常,对于这样的基准测试,您需要运行所有相关代码,以便在您进行真正的测试之前让 JIT 编译器有时间对其进行编译和优化。

有关 JIT 编译器的更多信息,请阅读this

您还应该查看this question 以了解有关基准测试的更多信息。

另一个可能导致速度变慢的原因是 JVM 可能仍在启动过程中,并在您对其进行计时时运行它自己的后台代码,从而导致速度变慢。

【讨论】:

    【解决方案2】:

    基准测试不是以这种方式完成的,您应该运行至少 1000 个循环作为“预热”,然后才开始测量。基准测试可能比看起来更复杂,应该仔细构建它,以免受到同时在内存中运行的其他程序等的影响。Herehere 你可以找到一些好的提示。

    【讨论】:

      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2021-12-13
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多