2010-07-29 5 views
2

이 두 Java 메소드 호출 중 하나가 프로세서 시간, 메모리 할당 및/또는 가비지 수집과 관련하여 전혀 다르게 동작하는지 궁금합니다.두 Java 세그먼트의 성능 차이가 있습니까?

SomeObject myObj = new SomeObject(); 
myObj.doSomething(); 

new SomeObject().doSomething(); 
+0

하나의 메소드를 호출하기 위해서만 객체를 자주 만들지 않기를 바랍니다. 또는 그러한 성능에 대해 걱정할 필요가 있습니다. –

+0

@ 톰 : 왜 그렇게 나쁠까요? 그는 한 가지 방법 만 실행하면 끝나고, 끝내면 그만하면됩니다. 마찬가지로, "새로운 Logger(). write ("공황 상태! 중단됩니다! ");" 우리는 로거 agan을 사용하지 않고 있습니다. 성능 차이에 관해서는, 한 번의 호출에 대해 나는 그것이 사소한 것이라고 확신한다. 그러나 이러한 것들이 합쳐집니다. 저장되는 나노초는 나노초입니다. – Jay

+0

자주. 안드로이드 애플리케이션에서 새 스레드를 생성하는 것으로부터 시작되었습니다. – iandisme

답변

5

생성 된 바이트 코드를 보면 :

// code 1 
new SomeObject().doSomething(); 

// bytecode 1 
    0: new #2; //class SomeObject 
    3: dup 
    4: invokespecial #3; //Method SomeObject."<init>":()V 
    7: invokevirtual #4; //Method SomeObject.doSomething:()V 
    10: return 

당신이 한 두 개 더 지침을 가지고 있음을 분명히 알 수 있습니다

// code 2 
SomeObject myObj = new SomeObject(); 
myObj.doSomething(); 

// bytecode 2 
    0: new #2; //class SomeObject 
    3: dup 
    4: invokespecial #3; //Method SomeObject."<init>":()V 
    7: astore_1 
    8: aload_1 
    9: invokevirtual #4; //Method SomeObject.doSomething:()V 
    12: return 

그 설명은 매우 중복과 최적화 아웃을 쉽게 보인다. JIT 컴파일러가 필요할 경우이를 처리 할 것입니다.

+0

이것은 내가 예상했던 라인을 따른 것입니다. 나보다 게으르다가 바이트 코드를 게시 해 주셔서 감사합니다! – iandisme

2

아니,이 질문의 본질에서 추측하는 것처럼 myObj로는, 다른 용도로 사용하면 사용되지 않는 것으로 가정        

+1

하 - 나는 이것을 기대하고 있었다. – iandisme

1

차이가 없어야합니다. 어느 쪽이든,이 코드가 오버 루프를 반복적으로 실행하는 반복문에 있으면 광고 오버레이에 대해 걱정할 필요가있는 유일한 시간입니다. 그렇다면 자바의 JIT 최적화가 당신을 아주 잘 돌봐 주므로 아무런 차이가 없어야합니다. 이 코드가 두 번째 예제와 같은 방식으로 작성된 것을 선호하지만 이는 나뿐입니다.

+0

대신 디버깅을 쉽게하기 때문에 변형 1을 선호합니다. 각 행에는 하나의 메소드 호출이 있으므로 각 메소드에 들어갈 것인지 스킵 할 것인지를 결정할 수 있습니다. 그런 식으로 알고리즘의 중간 결과를 검토하여 예상 값이 있는지 여부를 확인할 수도 있습니다. 이 메소드를 호출 할 때 원치 않는 부작용이 발생할 때 특히 중요합니다. –

0

두 가지의 유일한 차이점은 myObj 참조가 지워지지 않고 할당 된 개체가 path to root 인 개체의 일부가 가비지 수집되지 않는다는 것입니다.

4

차이점은 정확히 2 개의 JVM 바이트 코드로 1 개의 추가 기계 명령어로 변환됩니다. JIT는 변수를 사용하여 다른 작업을 수행하지 않으면 최적화 할 수 있습니다.

+0

고려해야 할 현명한 일이라면 머신 코드로의 순진한 변환은 일반적으로 바이트 코드와 마찬가지로 두 개의 명령 (로컬 프레임에 저장하고 그 다음에로드)을 도입합니다. –

+0

Nop에서 컴파일러는 레지스터 또는 스택에서 즉시 값을 재사용 할 수 있습니다. javac는 의미론으로 인해 2 개의 명령어 (하나의 저장소, 하나의로드)를 배치합니다. –

1

생성 된 바이트 코드가 다를 수 있지만 이것은 jit 컴파일러가 최적화하는 것이 더 쉬운 것 중 하나라고 생각합니다. 실제로 무엇을하는지에 따라 오브젝트 생성조차도 완벽하게 최적화 될 수 있습니다.

0

첫 번째 예제는 약간 덜 효율적입니다. 첫 번째 예에서 개체 참조는 함수 또는 닫는 블록의 끝까지 유지됩니다. 두 번째 예제에서 호출이 완료되면 개체 참조가 가비지 수집에 사용할 수 있습니다. 물론 실제로 가비지 수집되지 않을 수도 있습니다.

생성 된 바이트 코드를 확인하지 않았습니다. Java가 참조를 보유하는 방식에는 차이가있을 수 있지만, 어느 경우이든 사소한 것으로 의심됩니다.

관련 문제