2013-01-04 1 views
-2

클래스에 접근자를 제공하는 것이 좋거나 나쁜 OO 관행이라면 반사 성능 (메모리 소비 또는 CPU 시간)을 통해 객체의 특정 속성에 대한 액세스를 실행하고 있는지 알고 싶습니다.리플렉션을 사용하여 Java 클래스의 접근자를 구현하면 얼마나 성능이 저하됩니까?

이것을 구현하고 벤치 마크를 수행 했습니까? 벤치 마크를 수행 한 사람에 대해 알고 계십니까?

편집 :

때문에이 성능 저하가 나는 질문의 제목을 수정 한 분명 있음을 나타냅니다 일부 의견에 내가 구현하는 접근의 영향이 얼마나 나쁜 알고 싶습니다 나타냅니다 리플렉션과 함께.

편집 :

감사합니다. 친절한 댓글과 답변을 해주셔서 감사합니다.

package co.com.prueba.reflection; 

import java.lang.reflect.Field; 

public class A { 

private String s; 


public void setS(String s){ 
    this.s=s; 
} 

public String getS(){ 
    return this.s; 
} 

public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException { 

    System.out.println("Invoking .setAccesible(true) ..."); 
    A secondA = new A(); 
    for(int i=0; i<10; i++){ 
     long start = System.nanoTime(); 
     Field f = secondA.getClass().getDeclaredField("s"); 
     f.setAccessible(true); 
     f.get(secondA); 
     long end = System.nanoTime(); 
     System.out.println((end - start)); 
    } 

    System.out.println("Without invoking .setAccesible(true) ..."); 
    A firstA = new A();  
    for(int i=0; i<10; i++){ 
     long start = System.nanoTime(); 
     Field f = firstA.getClass().getDeclaredField("s");   
     f.get(firstA); 
     long end = System.nanoTime(); 
     System.out.println((end - start)); 
    } 

    System.out.println("Invoking the getter ..."); 
    A thirdA = new A(); 
    for(int i=0; i<10; i++){ 
     long start = System.nanoTime(); 
     thirdA.getS(); 
     long end = System.nanoTime(); 
     System.out.println((end - start)); 
    } 


} 

}

여기

있습니다 : @ 피터 Lawrey 및 @EJP의 종류 주석의 답변에 따라이 내가 의미하고 어떤 전에 내 질문에 구현 한 경우 알고 싶어 무엇인가 결과 :

enter image description here

여러분 모두 감사드립니다.

+3

반사가 항상 느립니다. – SLaks

+3

물론 변수에 액세스하는 것보다 속도가 느리고 무겁습니다.그리고 컴파일이 액세스의 일관성을 확인하지 않는다는 것과 같은 많은 다른 문제가 발생합니다. –

+0

정확히 무슨 뜻입니까? 접근 자 (getter 및 setters)는 리플렉션이 아닙니다. – Henry

답변

3

일반적인 기계에서는 반사를 통해 getter를 호출하는 데 약 3 ns가 소요됩니다. 세터는 거의 동일합니다. 게터가 인라인되거나 심지어 반사없이 제거 될 수 있기 때문에 상대적인 차이가 크다.

3ns가 얼마나 차이가 있습니까?

코드 예제를 제공했으며 결과는 어제 HERE입니다. ;)

+0

JIT 된 적이 있습니까? – assylias

+1

@assylias 직접 호출을 할당하지만 동일한 정도는 아닙니다. 코드가 워밍업되기 전에 setAccessible (true)을 사용하면 500 ns에 가깝고 그렇지 않은 경우 1500 ns에 가깝습니다. –

+0

@PeterLawrey 이것이 내 구현의 기반이었습니다. Tks. – juanpavergara

0

나는이게 thread이 일반적으로 성능에 대한 질문에 대답한다고 생각합니다. 이 blog이 정보를 얻는 데 도움이되기를 바랍니다. 벤치 마크 값. IBM - Reflection performance benchmark의 게시물과 같은 외부 링크가 있습니다. 벤치 마크 값에 대해 논의합니다.

0

Java Reflection Performance

예전보다 낫다는하지만 여전히 직접 변수에 접근보다 느린 (I 1.4 이전에 생각). 클래스와 모든 속성을 메모리에로드 한 다음 원하는 목록을 검색해야하기 때문이라고 생각합니다.

Google에서 가상 메소드 호출을 자르기 위해 Android 개발을 수행 할 때 변수를 직접 액세스하는 것이 좋습니다 (또는 적어도 atleast).

2

다른 사람들이 말하는 최소한의 성능을 얻으려면 에만 이미 존재하는 Method 개체에 대한 반사 호출이 필요하다는 것을 이해해야합니다. 모든 통화에서 조회를 수행하면 실적이 입니다.

관련 문제