在今天的牛客刷题中遇到一道这个题
先说结论,顺序从快到慢为:
- System.arraycopy
- clone
- Arrays.copyOf
- for循环逐一复制
System.arraycopy
源码如下所示:
@HotSpotIntrinsicCandidate
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
我们可以看到在方法上方有一个 @HotSpotIntrinsicCandidate 注解
该注解表示为了提升性能,在JVM里对该注解的进行了手写,这里要提一个叫JNI(Java Native Interface)的东西,普通的native方法通俗的讲就是编译后还要通过JNI再次编译成.cpp文件才能执行.而有 @HotSpotIntrinsicCandidate这个注解的方法在JVM里就是用.cpp文件写好的,所以就跳过了JNI阶段,所以速度就能提升,所以System.arraycopy是速度最快的
clone
源码如下所示
@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
可以看到,该方法也是有@HotSpotIntrinsicCandidate注解的,但是该注解有些写了对应的cpp文件,有些没有写,那我们当然可以知道,该方法是没有写的,所以速度比System.arraycopy要慢。
Arrays.copyOf
这道题我觉得是打错了,应该是Arrays.copyOf
源码如下所示
@HotSpotIntrinsicCandidate
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
可以看出这个方法也是有着 @HotSpotIntrinsicCandidate 注解的,但是他并不是native方法,也就是说明并没有对应的cpp,而我们可以很明显的看出其内部是直接调用了System.arraycopy方法,所以速度较慢
for方法
for方法,无论是复制基础数据类型还是对象类型,都是深复制,也就是直接复制值而不是复制引用,所以速度是最慢的。