이 두 Java 메소드 호출 중 하나가 프로세서 시간, 메모리 할당 및/또는 가비지 수집과 관련하여 전혀 다르게 동작하는지 궁금합니다.두 Java 세그먼트의 성능 차이가 있습니까?
SomeObject myObj = new SomeObject();
myObj.doSomething();
대
new SomeObject().doSomething();
이 두 Java 메소드 호출 중 하나가 프로세서 시간, 메모리 할당 및/또는 가비지 수집과 관련하여 전혀 다르게 동작하는지 궁금합니다.두 Java 세그먼트의 성능 차이가 있습니까?
SomeObject myObj = new SomeObject();
myObj.doSomething();
대
new SomeObject().doSomething();
생성 된 바이트 코드를 보면 :
// 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 컴파일러가 필요할 경우이를 처리 할 것입니다.
이것은 내가 예상했던 라인을 따른 것입니다. 나보다 게으르다가 바이트 코드를 게시 해 주셔서 감사합니다! – iandisme
차이가 없어야합니다. 어느 쪽이든,이 코드가 오버 루프를 반복적으로 실행하는 반복문에 있으면 광고 오버레이에 대해 걱정할 필요가있는 유일한 시간입니다. 그렇다면 자바의 JIT 최적화가 당신을 아주 잘 돌봐 주므로 아무런 차이가 없어야합니다. 이 코드가 두 번째 예제와 같은 방식으로 작성된 것을 선호하지만 이는 나뿐입니다.
대신 디버깅을 쉽게하기 때문에 변형 1을 선호합니다. 각 행에는 하나의 메소드 호출이 있으므로 각 메소드에 들어갈 것인지 스킵 할 것인지를 결정할 수 있습니다. 그런 식으로 알고리즘의 중간 결과를 검토하여 예상 값이 있는지 여부를 확인할 수도 있습니다. 이 메소드를 호출 할 때 원치 않는 부작용이 발생할 때 특히 중요합니다. –
두 가지의 유일한 차이점은 myObj
참조가 지워지지 않고 할당 된 개체가 path to root
인 개체의 일부가 가비지 수집되지 않는다는 것입니다.
차이점은 정확히 2 개의 JVM 바이트 코드로 1 개의 추가 기계 명령어로 변환됩니다. JIT는 변수를 사용하여 다른 작업을 수행하지 않으면 최적화 할 수 있습니다.
고려해야 할 현명한 일이라면 머신 코드로의 순진한 변환은 일반적으로 바이트 코드와 마찬가지로 두 개의 명령 (로컬 프레임에 저장하고 그 다음에로드)을 도입합니다. –
Nop에서 컴파일러는 레지스터 또는 스택에서 즉시 값을 재사용 할 수 있습니다. javac는 의미론으로 인해 2 개의 명령어 (하나의 저장소, 하나의로드)를 배치합니다. –
생성 된 바이트 코드가 다를 수 있지만 이것은 jit 컴파일러가 최적화하는 것이 더 쉬운 것 중 하나라고 생각합니다. 실제로 무엇을하는지에 따라 오브젝트 생성조차도 완벽하게 최적화 될 수 있습니다.
첫 번째 예제는 약간 덜 효율적입니다. 첫 번째 예에서 개체 참조는 함수 또는 닫는 블록의 끝까지 유지됩니다. 두 번째 예제에서 호출이 완료되면 개체 참조가 가비지 수집에 사용할 수 있습니다. 물론 실제로 가비지 수집되지 않을 수도 있습니다.
생성 된 바이트 코드를 확인하지 않았습니다. Java가 참조를 보유하는 방식에는 차이가있을 수 있지만, 어느 경우이든 사소한 것으로 의심됩니다.
하나의 메소드를 호출하기 위해서만 객체를 자주 만들지 않기를 바랍니다. 또는 그러한 성능에 대해 걱정할 필요가 있습니다. –
@ 톰 : 왜 그렇게 나쁠까요? 그는 한 가지 방법 만 실행하면 끝나고, 끝내면 그만하면됩니다. 마찬가지로, "새로운 Logger(). write ("공황 상태! 중단됩니다! ");" 우리는 로거 agan을 사용하지 않고 있습니다. 성능 차이에 관해서는, 한 번의 호출에 대해 나는 그것이 사소한 것이라고 확신한다. 그러나 이러한 것들이 합쳐집니다. 저장되는 나노초는 나노초입니다. – Jay
자주. 안드로이드 애플리케이션에서 새 스레드를 생성하는 것으로부터 시작되었습니다. – iandisme