使用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),我没有注意到任何值得注意的差异。所以,在我看来,只有更大的阵列受此影响。这是否更好地初始化方法外的数组并将其作为方法的输入而不是在其中声明?这对其他语言是否相同?什么是更好的方法还是取决于具体情况?非常感谢!
答案 0 :(得分:0)
我有预感 - 但这只是一种预感,而且仍然令人惊讶。
这是一个运行时间相对较长的方法 - 因此Hotspot可能会多次JIT编译,应用越来越多的优化。
第一种方法的字节码非常短,所以JITting很快。但是,第二种方法的字节代码将是 huge - 这可能意味着大部分时间花费在JIT上。
您可以通过多次运行每个方法来验证这一点,并打印出每次迭代所需的时间 - 我希望每种方法的“延迟”运行花费大约相同的时间。
同样,如果这会解决所有的差异,我会感到惊讶(我希望JIT优化初始化字节码一次,然后再忽略它),但它至少值得测试