2

使用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 倍)。这两种方法几乎相同,只是一种在其中初始化了一个数组,而另一种将初始化的数组作为输入。这如何或为什么会导致时间显着增加?另一方面,对于相当小的数组(<500),我没有注意到任何值得注意的差异。所以,在我看来,只有更大的数组会受此影响。这是否可以更好地在方法外部初始化数组并将其作为方法的输入而不是在内部声明它?其他语言也一样吗?有什么更好的方法还是取决于情况?多谢!

4

1 回答 1

0

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

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

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

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

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

于 2013-08-02T17:06:21.260 回答