在下面的代码和结果中,我们可以看到“Traverse2”比“Traverse1”快得多,实际上它们只是遍历了相同数量的元素。
1.这种差异是如何产生的?
2.将较长的交互放在较短的交互中会有更好的性能?
public class TraverseTest {
public static void main(String[] args)
{
int a[][] = new int[100][10];
System.out.println(System.currentTimeMillis());
//Traverse1
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < 10; j++)
a[i][j] = 1;
}
System.out.println(System.currentTimeMillis());
//Traverse2
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 100; j++)
a[j][i] = 2;
}
System.out.println(System.currentTimeMillis());
}
}
结果:
1347116569345
1347116569360
1347116569360
如果我把它改成
System.out.println(System.nanoTime());
结果将是:
4888285195629
4888285846760
4888285914219
这意味着如果我们把更长的interaction放在里面会有更好的表现。而且它似乎与缓存命中理论有些冲突。
最佳答案
我怀疑您在此微基准测试中看到的任何异常结果都是由于基准测试本身的缺陷造成的。
例如:
您的基准测试没有考虑“JVM 预热”效应,例如 JIT 编译器不会立即编译为 native 代码。 (这只会在代码执行一段时间后发生,并且 JVM 已经测量了一些使用次数以帮助优化。)处理这个问题的正确方法是将所有代码放入一个运行几次的循环中,然后丢弃由于热身效应,任何看起来“奇怪”的初始时间集。
基准测试中的循环理论上可以被优化掉。 JIT 编译器可能能够推断出它们不会执行任何影响程序输出的工作。
最后,我只想提醒您,像这样进行手动优化通常不是一个好主意……除非您有令人信服的证据表明手动优化是值得的,并且这段代码确实是应用程序花费了大量时间。
关于java - Java中多维数组的遍历性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12331959/