【问题标题】:Array Declared inside method makes a difference in time from an array Declared outside a method and used inside as an input在方法内部声明的数组与在方法外部声明并在内部用作输入的数组在时间上有所不同
【发布时间】:2013-08-04 01:00:10
【问题描述】:

使用java尝试解决一个数学问题,并寻找提高解决效率的方法,我得到了非常显着的执行时间大幅增加,不知道它是怎么来的。经过几次测试,我可能已经找到了答案,但我仍然不知道这是如何发生的或为什么会发生。

这里是显示这个时间差的测试代码:

public class arrayAcessTime {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        AccessTime();
    }

    public static long getLargestPrimeFactor(long l, int[] x)
    {
        long p = 0, n = l/2, r = (long) Math.sqrt(l), y = 49;

        for(long i = 13; i <= r;)
        {
            for(int j = 0; j<x.length; j++)
            {
                if (l % i == 0) 
                {
                  n = l/i;
                } 

                else 
                {
                   n = l / (i + 1); 
                }

                i+=x[j];
            }
        }

        return p;
    }

    public static long getLargestPrimeFactor(long l)
    {
        long p = 0, n = l/2, r = (long) Math.sqrt(l), y = 49;

     int x[] = {2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,         

      System.out.println("x size: " + x.length);

        for(long i = 13; i <= r;)
        {
            for(int j = 0; j<x.length; j++)
            {
                if (l % i == 0) 
                {
                  n = l/i;
                } 

                else 
                {
                   n = l / (i + 1); 
                }

                i+=x[j];
            }
        }

        return p;
    }

    public static void AccessTime() {

        int array2[] = {2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2,....} //too large to write here 


        long start;
        double diff;

        System.out.println("Array2 size: " + array2.length);

        start = System.currentTimeMillis();

        getLargestPrimeFactor(8798765600851475143L, array2);

        diff = (System.currentTimeMillis() - start) / 1000.0;

        System.out.println("Time: " + diff);


        start = System.currentTimeMillis();

        getLargestPrimeFactor(8798765600851475143L);

        diff = (System.currentTimeMillis() - start) / 1000.0;

        System.out.println("Time: " + diff);

    }
}

输出:

Array2 size: 5760
Time: 6.144
x size: 5760
Time: 30.225

如您所见,时间增加非常显着(大约 5 倍)。这两种方法几乎相同,只是一种在其中初始化了一个数组,而另一种将初始化的数组作为输入。这如何或为什么会导致时间显着增加?另一方面,对于相当小的数组(

【问题讨论】:

  • @Mysticial:该方法只被调用一次。
  • 减少的时间是因为你没有在计时中包括初始化数组需要多长时间。数组在计时的代码部分之外初始化。
  • @KevinCrowell:虽然这是正确的,但我不希望初始化数组需要 24 秒...
  • @JonSkeet 即使是非常大的阵列?他没有提供完整的数组,所以我不确定使用了多少元素。
  • 在初始化数组之前尝试开始计数的结果时间,以确保确定(也就是说,在声明数组之前开始计数并在方法之后完成,就像你知道的那样)。

标签: java arrays performance time


【解决方案1】:

我有一个预感 - 但这只是一种预感,而且仍然令人惊讶。

这是一个运行时间相对较长的方法 - 因此 Hotspot 可能会多次 JIT 编译它,应用越来越多的优化。

第一个方法的字节码很短,所以 JIT 很快。但是,您的第二种方法的字节码将是巨大的 - 这可能意味着大部分时间都花在 JITting 上。

您可以通过多次运行每个方法并打印出每次迭代需要多长时间来验证这一点 - 我预计每个方法的“后期”运行需要大约相同的时间。

再次,如果这能解释 所有 的差异,我会感到惊讶(我希望 JIT 优化初始化字节码一次,然后忽略它),但至少值得测试.

【讨论】:

  • 好吧,我在 c# 中尝试了类似的代码,并且两者的时间都差不多,大约 17 ,所以很可能它与 java 相关,因为它可以更快地通过第一个糊状物,因为它比第二。看到这一点仍然很高兴,如果没有体验过,就无法充分利用一种语言。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多