java为什么复制数组会减一_Java数组拷贝效率,为什么我得出的答案和网上不一样?...

本文通过实验对比了四种数组拷贝方法(for循环、System.arraycopy、Arrays.copyOf 和 clone)的性能,结果显示for循环和clone方法在不同数组规模下表现更优。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对这个问题还是比较感兴趣的,为此我也写了一个测试。

package test;

import java.util.Arrays;

public class Main {

public static int[] testSystemArrayCopy(int[] orginal) {

int[] target = new int[orginal.length];

System.arraycopy(orginal, 0, target, 0, target.length);

return target;

}

public static int[] testArraysCopyOf(int[] orginal) {

int[] target = Arrays.copyOf(orginal, orginal.length);

return target;

}

public static int[] testClone(int[] orginal) {

int[] target = orginal.clone();

return target;

}

public static int[] testFor(int[] orginal) {

int[] target = new int[orginal.length];

for (int i = 0; i < orginal.length; i++) {

target[i] = orginal[i];

}

return target;

}

public static void main(String args[]) {

final int LEN = 10_000;

final int TIMES = 100_000;

int[] original = new int[LEN];

for (int i = 0; i < original.length; i++) {

original[i] = i;

}

System.out.println("Size of arrays: " + LEN);

// // heat up

// testArraysCopyOf(original);

// testSystemArrayCopy(original);

// testClone(original);

// testFor(original);

long startTime, endTime;

long totalSize = 0L;

startTime = System.nanoTime();

for (int i = 0; i < TIMES; i++) {

int[] target = testFor(original);

totalSize += target.length;

target = null;

}

endTime = System.nanoTime();

System.out.println("for loop: " + (endTime - startTime) / 1_000_000 + "ms");

// startTime = System.nanoTime();

// for (int i = 0; i < TIMES; i++) {

// int[] target = testSystemArrayCopy(original);

// totalSize += target.length;

// target = null;

// }

// endTime = System.nanoTime();

// System.out.println("System.arrayCopy(): " + (endTime - startTime) / 1_000_000 + "ms");

// startTime = System.nanoTime();

// for (int i = 0; i < TIMES; i++) {

// int[] target = testArraysCopyOf(original);

// totalSize += target.length;

// target = null;

// }

// endTime = System.nanoTime();

// System.out.println("Arrays.copyOf(): " + (endTime - startTime) / 1_000_000 + "ms");

// startTime = System.nanoTime();

// for (int i = 0; i < TIMES; i++) {

// int[] target = testClone(original);

// totalSize += target.length;

// target = null;

// }

// endTime = System.nanoTime();

// System.out.println("clone(): " + (endTime - startTime) / 1_000_000 + "ms");

System.out.println("total size: " + totalSize);

}

}

测试是在我的个人电脑上完成的,操作系统是 Windows 10, Java 版本 1.8。

每轮测试只执行一种方法,预热环节被我删了,因为现在每轮里面会执行多次,预热对结果的影响应该很小。当然,加上也是可以的。

再来说说测试时使用的参数。我使用的是下面的参数来运行的:

-Xms2g -Xmx2g -Xmn1g

初始和最大内存都是 2GB,这样可以最大程度减小 JVM 扩展堆时的开销。

每个用例(指不同的数组规模)都执行两轮,先按照正序执行一轮,再逆序执行一轮。

下面是整理后的结果:

Size of arrays: 10,000 (100k times)

# 1st

for loop: 592ms

System.arrayCopy(): 636ms

Arrays.copyOf(): 633ms

clone(): 681ms

# 2nd

for loop: 587ms

System.arrayCopy(): 622ms

Arrays.copyOf(): 628ms

clone(): 674ms

Size of arrays: 100,000 (10k times)

# 1st

for loop: 828ms

System.arrayCopy(): 849ms

Arrays.copyOf(): 801ms

clone(): 855ms

# 2nd

for loop: 821ms

System.arrayCopy(): 825ms

Arrays.copyOf(): 804ms

clone(): 874ms

Size of arrays: 1,000,000 (10k times)

# 1st

for loop: 7896ms

System.arrayCopy(): 9454ms

Arrays.copyOf(): 10362ms

clone(): 6934ms

# 2nd

for loop: 6789ms

System.arrayCopy(): 9318ms

Arrays.copyOf(): 9521ms

clone(): 6909ms

Size of arrays: 10,000,000 (1k times)

# 1st

for loop: 7697ms

System.arrayCopy(): 9236ms

Arrays.copyOf(): 9242ms

clone(): 8396ms

# 2nd

for loop: 7926ms

System.arrayCopy(): 9303ms

Arrays.copyOf(): 9203ms

clone(): 8500ms

Size of arrays: 100,000,000 (100 times)

# 1st

for loop: 7780ms

System.arrayCopy(): 8817ms

Arrays.copyOf(): 8886ms

clone(): 8808ms

# 2nd

for loop: 7772ms

System.arrayCopy(): 8818ms

Arrays.copyOf(): 9204ms

clone(): 9088ms

根据结果绘制的图表:

fd5cc10b19ab6be799693eb22bdd9bd2.png

结论基本与楼主的差不多,怎么看都是 for 循环和 clone 比较快。

但是不太清楚为什么与楼上用 jmh 测试的结果差别这么大。但是如果让我选,我还是比较愿意相信我自己实际运行后得出的结论,因为使用测试工具,我也不知道它内部是如何完成测试的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值