2011-09-01 6 views
2

나는 C 배경에서 왔습니다. 그래서 저는 여전히 자바로 글을 쓸 때 메모리 관리를 허락하지 않으려 고합니다. 몇 가지 문제가 있습니다. 몇 가지 문제가 있습니다.Java에서 for 루프 안에 배열을 선언하는 것이 얼마나 좋지 않습니까?

코드 샘플 1 :

double[] array; 
for (int i=0; i<n; ++i) { 
    array = calculateSomethingAndReturnAnArray(i); 
    if (someFunctionOnArrays(array)) { 
     // DO ONE THING 
    } else { 
     // DO SOME OTHER THING 
    } 
} 

코드 샘플 2 : 여기

for (int i=0; i<n; ++i) { 
    double[] array = calculateSomethingAndReturnAnArray(i); 
    if (someFunctionOnArrays(array)) { 
     // DO ONE THING 
    } else { 
     // DO SOME OTHER THING 
    } 
} 

여기에, 유일한 차이점은 double[] array가 선언되는 동일한 루틴을 작성하는 두 가지 방법이 있습니다 private double[] calculateSomethingAndReturnAnArray(int i)은 항상 동일한 길이의 배열을 반환합니다. 코드 샘플 2으로 혐오감을 갖습니다. 기존 배열을 덮어 쓸 수있을 때마다 각 반복마다 새 배열을 만들기 때문입니다. 그러나 나는 이것이 내가 앉아서 Java가 상황을 처리하도록해야하는 시대 중 하나라고 생각합니다.

다른 방법보다 한 가지 방법을 선호하거나 Java에서 진정으로 동일한 이유는 무엇입니까?

+6

두 시나리오 모두에서 새 배열을 만듭니다. 당신은 단지 * 첫 번째 샘플에서 배열을 한 번만 선언하는 것입니다 (저장소는 단지 참조이므로 32 비트입니다). 그러나 아마도'calculateSomethingAndReturnAnArray'는 항상 새로운 배열을 인스턴스화합니다. 이것은 실제 비용이있는 곳입니다. –

+0

@Kirk ... 대답을 꺼내는 마음? – PengOne

+0

Meh, @ Mark의 대답은 훨씬 좋습니다. ;) –

답변

8

, 당신은 단지 새로운 변수를 만들, 그것은 동등의 그것을 반복하면, 변수 (참조하는 대상의 위치를 ​​보유 할 변수)는 한 번만 할당됩니다. 변수를 루프 내에 만들면 변수는 각 반복에서 다시 할당 될 수 있지만 내 추측 컴파일러이거나 최적화 단계에서 JIT가이를 수정합니다.

마이크로 최적화라고 생각합니다. 코드의이 부분에 문제가있는 경우 스펙이 아닌 측정을 기반으로 결정해야합니다. 코드의이 부분에 문제가 있다면, 의미 론적으로 올바른 것을하고 이해할 수있는 범위에서 변수를 선언해야합니다.

본 내용은 similar question about best practices입니다.

+0

설명 및 참조 주셔서 감사합니다. – PengOne

0

둘 다 각 반복마다 새 배열을 만듭니다. 그것들은 동일한 의미를 갖는다. 당신이 외부 변수를 만들 경우

Object foo; 
for(...){ 
    foo = func(...); 
} 

: 당신이 배열 할당하지 있기 때문에 여기에 배열에 대한 특별한 아무것도 없습니다

1

초기화 표현을 사용하지 않고 로컬 변수를 선언하면 작업이 전혀 수행되지 않습니다. 변수가 초기화되면 작업이 수행됩니다. 첫 번째 경우는 array 후 사용될 수 있다는

double[] array; 
for (int i=0; i<n; ++i) { 
    array = calculateSomethingAndReturnAnArray(i); 
    // ... 
} 

for (int i=0; i<n; ++i) { 
    double[] array = calculateSomethingAndReturnAnArray(i); 
    // ... 
} 

가 (심지어 애매한 없습니다

따라서, 다음 의미 및 성능면과 동일 루프가 끝나면, array은 루프 다음에 명확한 값을 가져야하며, 초기화에 이니셜 라이저를 추가하지 않으면 예외가됩니다.double[] array = null;)는 마이크로 최적화에 대한 @ 마크 엘리엇의 지점에 정교하게


는 (내가 언급 한 바와 같이 있기 때문에

  • 이 정말 진짜 최적화보다는 최적화하는 시도입니다) 효과가 없어야합니다.

  • Java 컴파일러가 실제로 double[] array;에 대해 간단한 코드를 생성하더라도 실행 시간은 루프 본문 및 응용 프로그램 전체의 총 실행 시간과 비교할 때 중요하지 않을 가능성이 있습니다 . 따라서 이것은 무의미한 최적화 일 가능성이 가장 높습니다.

  • 이것이 가치있는 최적화라고해도 특정 대상 플랫폼에 맞게 최적화했는지 고려해야합니다. 즉 하드웨어와 JVM 버전의 특정 조합입니다. 이와 같은 미세 최적화는 다른 플랫폼에서는 최적이 아닐 수 있으며 이론적으로 최적화가되지 않을 수 있습니다.

요약하면 Java 코드를 작성할 때 이와 같은 것에 집중하면 시간을 낭비하는 경향이 있습니다. 성능이 응용 프로그램의 관심사 인 경우 MACRO 수준 성능에 중점을 둡니다. 예 : 알고리즘 복잡성, 데이터베이스/쿼리 디자인, 네트워크 상호 작용 패턴 등이 포함됩니다.

관련 문제