시스템을 사용하는 것이 좋습니까?어레이를 복사하기 위한 for 루프가 아닌 arraycopy(...)를 선택하십시오.
2개의 작은 어레이를 조합한 새로운 오브젝트 어레이를 만들고 싶습니다.
null일 수는 없지만 크기가 0일 수 있습니다.
나는 이 두 가지 방법 중 하나를 선택할 수 없다: 그것들이 동등한가 아니면 더 효율적인가(예를 들어 시스템).arraycopy()는 전체 청크를 복사합니까?
MyObject[] things = new MyObject[publicThings.length+privateThings.length];
System.arraycopy(publicThings, 0, things, 0, publicThings.length);
System.arraycopy(privateThings, 0, things, publicThings.length, privateThings.length);
또는
MyObject[] things = new MyObject[publicThings.length+privateThings.length];
for (int i = 0; i < things.length; i++) {
if (i<publicThings.length){
things[i] = publicThings[i]
} else {
things[i] = privateThings[i-publicThings.length]
}
}
유일한 차이점은 코드의 외관뿐입니까?
EDIT: 링크된 질문 감사합니다만, 아직 해결되지 않은 논의가 있는 것 같습니다.
정말 더 빠른가요?it is not for native types
: byte[ ] , " 오 、 char [ ] 합니까?아니죠다른 모든 경우, 활자체크가 실행되는데, 내 경우 같다면... 아닌가?
연계된에서는 '하다, , 하다'the size matters a lot
> system size > 24 "size" > "size.이 경우arraycopy() 보보10 보 array array array array array 。
지금 나는 정말 혼란스럽다.
public void testHardCopyBytes()
{
byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
byte[] out = new byte[bytes.length];
for(int i = 0; i < out.length; i++)
{
out[i] = bytes[i];
}
}
public void testArrayCopyBytes()
{
byte[] bytes = new byte[0x5000000]; /*~83mb buffer*/
byte[] out = new byte[bytes.length];
System.arraycopy(bytes, 0, out, 0, out.length);
}
JUnit의 경우
는 HardCopyBytes를 완료하는 데 0..
...
0..testArrayCopyBytes는 0.086s입니다.
가상 머신에 따라 다르지만 단일 어레이 요소를 복사하는 대신 메모리 블록을 복사하는 것처럼 보입니다.이치노
★★★★★★
스스 。の 。arraycopy のanceanceanceanceanceance 。바이트 대신 문자열이 사용되고 배열이 작은 경우(사이즈 10) 다음과 같은 결과가 나타납니다.
String HC: 60306 ns
String AC: 4812 ns
byte HC: 4490 ns
byte AC: 9945 ns
어레이의 사이즈가 0x1000000일 때의 모습을 다음에 나타냅니다.시스템처럼 보여요.어레이 복사는 대규모 어레이에서 확실히 유리합니다.
Strs HC: 51730575 ns
Strs AC: 24033154 ns
Bytes HC: 28521827 ns
Bytes AC: 5264961 ns
★★★★★★★★★★★★★★★★!
대런 씨, 참고 문헌이 다르게 복사된다는 점을 지적해 주셔서 감사합니다.그것은 이것을 훨씬 더 흥미로운 문제로 만들었다!
Arrays.copyOf(T[], int)
가 읽기 쉬워집니다.에서는 「」를 사용합니다.System.arraycopy()
네이티브 콜입니다.
더 빨리 할 수 없어!
가상 시스템에 따라 다르지만 시스템에 따라 다릅니다.arraycopy를 사용하면 네이티브 퍼포먼스에 가장 가까운 성능을 얻을 수 있습니다.
저는 임베디드 시스템(성능이 중요한 곳) 및 모든 시스템용 자바 개발자로 2년간 일해 왔습니다.Arraycopy를 사용할 수 있습니다.기존 코드에서 사용하는 것을 대부분 사용하고 있습니다.퍼포먼스가 문제가 될 때는 루프보다 항상 우선합니다.퍼포먼스가 큰 문제가 되지 않는다면 루프로 하겠습니다.훨씬 읽기 쉬워요.
추측이나 오래된 정보에 의존하는 대신 캘리퍼를 사용하여 몇 가지 벤치마크를 실행했습니다.실제로 캘리퍼에는 이 질문을 정확하게 측정하는 를 포함한 몇 가지 예가 포함되어 있습니다.넌 도망치기만 하면 돼
mvn exec:java -Dexec.mainClass=com.google.caliper.runner.CaliperMain -Dexec.args=examples.CopyArrayBenchmark
결과는 2010년 중반의 MacBook Pro(인텔 Arrandale i7, 8 GiB RAM 탑재 MacOS 10.11.6)에서 실행되는 Oracle의 Java HotSpot(TM) 64비트 서버 VM 1.8.0_31-b13을 기반으로 합니다.원시 타이밍 데이터를 게시하는 것은 유용하지 않다고 생각합니다.대신, 결론을 뒷받침하는 시각화와 함께 요약하겠습니다.
요약:
- 매뉴얼 작성
for
각 요소를 새로 인스턴스화된 어레이에 복사하는 루프는 짧은 어레이든 긴 어레이든 결코 유리하지 않습니다. Arrays.copyOf(array, array.length)
둘 다 일관되게 빠릅니다.이 두 기술은 성능 면에서 거의 동일합니다. 어느 것을 선택하느냐는 취향의 문제입니다.System.arraycopy(src, 0, dest, 0, src.length)
거의 와 같은 속도이다Arrays.copyOf(array, array.length)
그리고.array.clone()
단, 그다지 일관성이 있는 것은 아닙니다.(50000 의 경우는, 케이스를 참조해 주세요).int
s) 그 때문에, 콜의 장황함도 추천합니다.System.arraycopy()
어떤 요소가 어디에 복사되는지를 세밀하게 제어해야 할 경우.
타이밍 플롯은 다음과 같습니다.
할 수 없다Arrays.copyOf
보다 빠르다System.arraycopy
이것이 실시이기 때문에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;
}
다음과 같은 네이티브 메서드 실행Arrays.copyOf(T[], int)
에는 오버헤드가 있지만 JNI를 사용하여 실행하고 있기 때문에 고속이 아닌 것은 아닙니다.
가장 쉬운 방법은 벤치마크와 테스트를 작성하는 것입니다.
확인하실 수 있습니다.Arrays.copyOf(T[], int)
평소보다 빠르다for
고리.
벤치마크 코드는 다음과 같습니다.
public void test(int copySize, int copyCount, int testRep) {
System.out.println("Copy size = " + copySize);
System.out.println("Copy count = " + copyCount);
System.out.println();
for (int i = testRep; i > 0; --i) {
copy(copySize, copyCount);
loop(copySize, copyCount);
}
System.out.println();
}
public void copy(int copySize, int copyCount) {
int[] src = newSrc(copySize + 1);
int[] dst = new int[copySize + 1];
long begin = System.nanoTime();
for (int count = copyCount; count > 0; --count) {
System.arraycopy(src, 1, dst, 0, copySize);
dst[copySize] = src[copySize] + 1;
System.arraycopy(dst, 0, src, 0, copySize);
src[copySize] = dst[copySize];
}
long end = System.nanoTime();
System.out.println("Arraycopy: " + (end - begin) / 1e9 + " s");
}
public void loop(int copySize, int copyCount) {
int[] src = newSrc(copySize + 1);
int[] dst = new int[copySize + 1];
long begin = System.nanoTime();
for (int count = copyCount; count > 0; --count) {
for (int i = copySize - 1; i >= 0; --i) {
dst[i] = src[i + 1];
}
dst[copySize] = src[copySize] + 1;
for (int i = copySize - 1; i >= 0; --i) {
src[i] = dst[i];
}
src[copySize] = dst[copySize];
}
long end = System.nanoTime();
System.out.println("Man. loop: " + (end - begin) / 1e9 + " s");
}
public int[] newSrc(int arraySize) {
int[] src = new int[arraySize];
for (int i = arraySize - 1; i >= 0; --i) {
src[i] = i;
}
return src;
}
System.arraycopy()
JNI(Java Native Interface)를 사용하여 어레이(또는 일부)를 복사하기 때문에 여기서 확인할 수 있듯이 매우 고속입니다.
System.arraycopy()
는 메모리에서 직접 복사 조작을 실행하는 네이티브콜입니다단일 메모리 복사는 항상 for 루프보다 빠릅니다.
언급URL : https://stackoverflow.com/questions/18638743/is-it-better-to-use-system-arraycopy-than-a-for-loop-for-copying-arrays
'source' 카테고리의 다른 글
ArrayList에서 임의 항목 검색 (0) | 2022.09.03 |
---|---|
Vuetify 자동 완성 유사 항목이 표시되지 않습니다. (0) | 2022.09.03 |
줄바꿈(JLABEL) (0) | 2022.09.03 |
C#의 네임스페이스와 Java 패키지의 차이 (0) | 2022.09.03 |
디폴트 패키지 내의 Java-classes에 액세스하려면 어떻게 해야 합니까? (0) | 2022.09.03 |