Development Tip

더 효율적인 것 : System.arraycopy 또는 Arrays.copyOf?

yourdevel 2020. 10. 28. 21:12
반응형

더 효율적인 것 : System.arraycopy 또는 Arrays.copyOf?


, Bloch toArray방법은 ArrayList둘 다 사용 하여 배열을 복사합니다.System.arraycopyArrays.copyOf

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

이 두 가지 복사 방법을 어떻게 비교할 수 있으며 언제 어떤 방법을 사용해야합니까?


차이점은 Arrays.copyOf요소를 복사 할뿐만 아니라 새 배열도 생성한다는 것입니다. System.arraycopy기존 어레이로 복사합니다.

내부적으로 새 배열을 채우는 Arrays.copyOf데 사용하는 것을 볼 수 있듯이 의 소스는 다음과 같습니다 System.arraycopy.

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    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;
}

하지만 System.arraycopy기본적으로 구현하고 있습니다 때문에 될 수 1 빠른 자바 루프에 비해, 그것은 빨리 예상대로 항상하지 않습니다. 이 예를 고려하십시오.

Object[] foo = new Object[]{...};
String[] bar = new String[foo.length];

System.arraycopy(foo, 0, bar, 0, bar.length);

이 경우 foobar배열 의 기본 유형은 기본 유형 이 다르므로의 구현에서는 arraycopy복사 된 모든 참조의 유형을 확인하여 실제로 String 인스턴스에 대한 참조인지 확인해야합니다. 배열 내용의 단순한 C 스타일 memcopy보다 훨씬 느립니다.

다른 점은 후드 아래에서 Arrays.copyOf사용 한다는 것 System.arraycopy입니다. 따라서 System.arraycopy그것의 얼굴에 느린 안된다 2 이상 Arrays.copyOf. 그러나 어떤 경우에는 리플렉션을 사용하여 새 배열을 만드는 것을 ( 위에 인용 코드에서) 볼 수 있습니다 Arrays.copyOf. 따라서 성능 비교는 간단하지 않습니다.

이 분석에는 몇 가지 결함이 있습니다.

  1. 우리는 특정 버전의 Java에서 구현 코드를보고 있습니다. 이러한 방법은 효율성에 대한 이전 가정을 무효화하여 변경 될 수 있습니다.

  2. 우리는 JIT 컴파일러가 이러한 메서드에 대해 영리한 특수 사례 최적화를 수행 할 수 있다는 가능성을 무시하고 있습니다. 그리고 분명히 이것은 다음과 함께 발생합니다 Arrays.copyOf. 소규모 어레이의 경우 Arrays.copyOf가 System.arraycopy보다 2 배 빠른 이유를 참조하십시오 . . 이 메소드는 현재 세대 Java 구현에서 "내재적"입니다. 즉, JIT 컴파일러가 Java 소스 코드에있는 내용을 무시합니다!

그러나 어느 쪽이든 두 버전 차이O(1)(즉, 어레이 크기와 무관) 비교적 작습니다. 따라서 내 조언은 코드를 가장 쉽게 읽을 수있는 버전을 사용하고 프로파일 링 이 중요하다고 말하면 어느 것이 더 빠른지에 대해서만 걱정하는 것입니다 .


1- 더 빠를 있지만 JIT 컴파일러가 차이가없는 수작업 코드 루프를 최적화하는 훌륭한 작업을 수행 할 수도 있습니다 .


배열 정확한 복사본을 원할 경우 (예 : 방어 복사를 수행하려는 경우) 배열을 복사하는 가장 효과적인 방법은 배열 객체의 clone()방법을 사용하는 것입니다 .

class C {
    private int[] arr;
    public C(int[] values){
        this.arr = values.clone();
    }
}

나는 그것의 성능을 테스트하는 것을 귀찮게하지 않았지만, 그것이 모두 네이티브 (할당 및 호출 중 복사)이기 때문에 꽤 빠르며 복제는 일종의 특별한 JVM 축복 방식의 객체 복사 (그리고 그것은 대부분 다른 목적으로 악) 일부 "단축키"를 취할 수 있습니다.

개인적으로 clone다른 복사 방법보다 느리 더라도 여전히 사용 합니다. 왜냐하면 읽기가 더 쉽고 글을 쓸 때 망칠 가능성이 거의 없기 때문입니다. System.arrayCopy, 반면에 ...


System.arrayCopy가 훨씬 빠릅니다. Java 랜드 외부에서 직접 메모리 사본을 사용하기 때문에 시스템에 있습니다. 가능하면 사용하십시오.


Sun의 Arrays.copyOf () 구현을 보셨습니까?

 public static int[] copyOf(int[] original, int newLength) {
    int[] copy = new int[newLength];
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

보시다시피 System.arraycopy()내부적으로 사용 하므로 성능은 동일합니다.


System.arrayCopy is implemented natively, and hence will be faster than any Java code. I recommend you to use it.


Instead of debating, these are the actual results. Clearly, your choice will depend on how much data you want to copy.

byte[] copy performance test

10,000,000 iterations 40b array.copyOfRange: 135ms systems.arraycopy: 141ms

10,000,000 iterations 1000b array.copyOfRange: 1861ms systems.arraycopy: 2211ms

10,000,000 iterations 4000b array.copyOfRange: 6315ms systems.arraycopy: 5251ms

1,000,000 iterations 100,000b array.copyOfRange: 15,198ms systems.arraycopy: 14783ms


If you look at both the source code for System.arraycopy() of and Array.copyOf(), for performance.

System.arraycopy() is C code, it operates directly on your array, it does not return any values, and because of that it should operate much faster than Array.copyOf(). Nonetheless, if you need a new array to be created or if you just need the value of the copy operation then you have to create a new array for that, set the new array length, etc... Thus, you can't do a return System.arraycopy(source, 0, destination, 0, length).

For what Array.copyOf() can do then, it make a new array for you. You can assign the return value from Array.copyOf() to an array or returning it from a method as Array.copyOf() return to you a value instead of operating directly on your destination array. Thus, your code will look much cleaner. Nonetheless, for the cost of performance, Array.copyOf() is a generic type method and it does not know ahead of time what it will be working with. Thus, it has to call Array.newInstance() or new Object() and then cast it to the input's array type.

So to sum up. Use System.arraycopy() because of performance. Use Array.copyOf() for cleaner code.


      class ArrayCopyDemo {
   public static void main(String[] args) {
    char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
            'i', 'n', 'a', 't', 'e', 'd' };
    char[] copyTo = new char[7];

    System.arraycopy(copyFrom, 2, copyTo, 0, 7);
    System.out.println(new String(copyTo));
}
 }

참고URL : https://stackoverflow.com/questions/2589741/what-is-more-efficient-system-arraycopy-or-arrays-copyof

반응형