在Java中,对于原始数组,重用数组是否比重复创建数组快得多?
在Java中,对于原始数组,重用数组是否比重复创建数组快得多 以下代码段比较了这两种情况:(a)通过System.arrayCopy重用数组与(b)在密集循环中重复创建指定值的数组在Java中,对于原始数组,重用数组是否比重复创建数组快得多?,java,Java,在Java中,对于原始数组,重用数组是否比重复创建数组快得多 以下代码段比较了这两种情况:(a)通过System.arrayCopy重用数组与(b)在密集循环中重复创建指定值的数组 public static void testArrayAllocationVsCopyPerformance() { long time = System.currentTimeMillis(); final int length = 3000; boolean[] array = new
public static void testArrayAllocationVsCopyPerformance() {
long time = System.currentTimeMillis();
final int length = 3000;
boolean[] array = new boolean[length];
boolean[] backup = new boolean[length];
//for (int j = 0; j < length; j++) {
// backup [j] = true;
//}
for (int i = 0; i < 10000000; i++) {
//(a). array copy
//System.arraycopy(backup, 0, array, 0, length);
//(b). reconstruct arrays
array = new boolean[length];
//for (int j = 0; j < length; j++) {
// array[j] = true;
//}
}
long millis = System.currentTimeMillis() - time;
System.out.println("Time taken: " + millis + " milliseconds.");
System.exit(0);
}
public static void testArrayAllocationVsCopyPerformance(){
长时间=System.currentTimeMillis();
最终整数长度=3000;
布尔[]数组=新的布尔值[长度];
布尔值[]备份=新布尔值[长度];
//对于(int j=0;j
在我的电脑上,(b)平均需要2600毫秒左右,而(a)平均需要450毫秒左右。对于使用不同的值重新创建数组,性能差距会更大:(b)平均需要3750毫秒左右,而(a)保持不变,平均仍为450毫秒
在上面的代码段中,如果将“boolean”更改为“int”,结果是类似的:重用int数组大约需要重新创建数组的三分之一。此外,(b)的可读性也不远低于(a);(b) 与不需要“备份”数组的(a)相比,其可读性稍差
然而,对于stackoverflow或stackexchange中有关Java对象创建的类似问题,答案总是像“在成为瓶颈之前不要对其进行优化”,“现在的JIT或JVM句柄可以比您更好更快地处理这些问题”,“保持简单易读”,诸如此类的回答通常会受到观众的欢迎
问题是:上面的性能比较代码段是否可以表明,与使用短期基本数组的数组重新创建wrt相比,数组复制要快得多?上面的片段有缺陷吗?或者人们仍然不应该优化它,直到它成为一个瓶颈,等等
上面的性能比较代码段是否可以表明,与使用short重新创建阵列相比,阵列复制要快得多
活动基元数组
是的,但是你不需要证明。数组在内存中占据连续的空间System.arraycopy
是一个本机函数,专门用于复制阵列。很明显,它比创建数组、在数组上迭代、每次迭代时增加计数器、检查布尔表达式循环是否应该终止、将原语分配到数组中的特定位置等都要快
您还应该记住,现在的编译器非常智能,它们可能会用更高效的版本替换您的代码。在这种情况下,您不会在编写的测试中观察到任何差异。另外,请记住,Java使用即时编译器,它可能会在您多次运行代码后对代码进行优化,并且它决定了优化是值得的
上面的片段有缺陷吗
是的,它有缺陷。你在这里做的是微基准测试。然而,你还没有做任何热身阶段。我建议多读一些关于这个话题的书
或者人们仍然不应该优化它,直到它成为一个瓶颈,
等等
永远不要过早地进行优化。如果存在性能问题,请在启用探查器的情况下运行代码,确定瓶颈并修复问题
然而,你也应该使用一些常识。如果您有一个
列表
,并且正在前面添加元素,请使用链接列表
,而不是数组列表
。如果需要复制整个阵列,请使用System.arraycopy
,而不是在其上循环并手动执行。重用速度更快,因为它不需要内存分配。这不适用于对象引用;重复使用它们有些毫无意义,因为它什么也做不到。”或者“在最后一句话中,这是一个错误的选择:上面的性能比较片段可能很好地显示了时间差异,人们仍然不应该优化它,直到它成为瓶颈。实际上有四种可能性,而不是两种:(重新)使用现有的数组和arraycopy到其中;使用现有数组并分配给它;分配新数组并将arraycopy放入其中(这是Arrays.copyOf
为您所做的);分配新数组并分配给它。性能只在这项工作做得很多的情况下才重要,而且正如所回答的,当完成足够多的JIT时,性能会发生变化。此外,如果您分配了大量数组(或对象),这将增加实际使用中GC的聚合成本,但您无法衡量一个项目的效果。现有的5000个左右的答案都是正确的。