Development Tip

System.arraycopy가 Java에서 기본 제공되는 이유는 무엇입니까?

yourdevel 2020. 10. 12. 08:13
반응형

System.arraycopy가 Java에서 기본 제공되는 이유는 무엇입니까?


Java 소스에서 System.arraycopy가 기본 메서드라는 사실에 놀랐습니다.

물론 그 이유는 더 빠르기 때문입니다. 그러나 코드가 더 빠르게 사용할 수있는 기본 트릭은 무엇입니까?

원래 배열을 반복하고 각 포인터를 새 배열에 복사하지 않는 이유는 무엇입니까? 이것은 느리고 성가신 일이 아닙니다.


네이티브 코드에서는 n 개의 고유 한 복사 작업이 아니라 단일 memcpy/ 로 수행 할 수 있습니다 . 성능의 차이는 상당합니다.memmove


Java로 작성할 수 없습니다. 네이티브 코드는 Object 배열과 기본 배열 간의 차이를 무시하거나 제거 할 수 있습니다. 자바는 적어도 효율적으로 할 수 없습니다.

그리고 중첩 배열에 필요한 의미 체계 때문에 단일으로 작성할 수 없습니다memcpy() .


물론 구현에 따라 다릅니다.

HotSpot은이를 "내재"로 취급하고 호출 사이트에 코드를 삽입합니다. 그것은 느린 오래된 C 코드가 아니라 기계 코드입니다. 이것은 또한 메서드의 서명 문제가 크게 사라짐을 의미합니다.

단순 복사 루프는 명백한 최적화를 적용 할 수있을만큼 간단합니다. 예를 들어 루프 풀기. 정확히 발생하는 일은 다시 구현에 따라 다릅니다.


내 자신의 테스트에서 다중 차원 배열을 복사하는 System.arraycopy ()는 for 루프를 인터리빙하는 것보다 10 ~ 20 배 빠릅니다.

float[][] foo = mLoadMillionsOfPoints(); // result is a float[1200000][9]
float[][] fooCpy = new float[foo.length][foo[0].length];
long lTime = System.currentTimeMillis();
System.arraycopy(foo, 0, fooCpy, 0, foo.length);
System.out.println("native duration: " + (System.currentTimeMillis() - lTime) + " ms");
lTime = System.currentTimeMillis();

for (int i = 0; i < foo.length; i++)
{
    for (int j = 0; j < foo[0].length; j++)
    {
        fooCpy[i][j] = foo[i][j];
    }
}
System.out.println("System.arraycopy() duration: " + (System.currentTimeMillis() - lTime) + " ms");
for (int i = 0; i < foo.length; i++)
{
    for (int j = 0; j < foo[0].length; j++)
    {
        if (fooCpy[i][j] != foo[i][j])
        {
            System.err.println("ERROR at " + i + ", " + j);
        }
    }
}

이것은 다음을 인쇄합니다.

System.arraycopy() duration: 1 ms
loop duration: 16 ms

몇 가지 이유가 있습니다.

  1. JIT는 수동으로 작성된 C 코드만큼 효율적인 저수준 코드를 생성 할 가능성이 낮습니다. 낮은 수준의 C를 사용하면 일반 JIT 컴파일러에 대해 수행 할 수없는 많은 최적화가 가능합니다.

    수작업으로 작성된 C 구현의 몇 가지 트릭과 속도 비교는이 링크를 참조하십시오 (memcpy, 원칙은 동일).이 최적화 Memcpy를 확인 하면 속도가 향상됩니다.

  2. C 버전은 배열 구성원의 유형과 크기에 거의 독립적입니다. 배열 내용을 원시 메모리 블록 (예 : 포인터)으로 가져올 수있는 방법이 없기 때문에 Java에서 동일한 작업을 수행 할 수 없습니다.

참고 URL : https://stackoverflow.com/questions/2772152/why-is-system-arraycopy-native-in-java

반응형