java 코드 최적화 - 불필요한 대상 만들기 피하기

3485 단어
일반적으로 필요할 때마다 같은 기능을 가진 새로운 대상을 만드는 것이 아니라 대상을 다시 사용하는 것이 좋다.중용하는 방식은 빠르고 유행한다.만약 대상이 변할 수 없다면, 그는 시종 중용될 수 있을 것이다.

불변 객체 재사용


스트링 클래스의 예를 들어 스트링 클래스의 상수는 값이 부여되면 변경할 수 없고, 항상 다시 사용될 수 있다.
// , 
String s1 = new String("hello world");

우리는 아래의 방식을 이렇게 사용해야 한다.
//java , , 
String s1 = "hello world";

정적 공장 방법과 구조기를 동시에 제공하는 불가변류는 구조기가 아닌 정적 공장 방법을 사용하여 불필요한 대상을 만들 수 있다.예를 들어, 정적 플랜트 방법Boolean.value Of(String)는 Boolean(String)보다 좋습니다.구조기는 호출될 때마다 새로운 대상을 만들고 정적 공장 방법은 만들지 않는다.
변하지 않는 대상을 중용하는 것 외에 수정되지 않는 가변 대상도 중용할 수 있다.

수정되지 않은 가변 객체 재사용


일반적인 예: Date 객체만약 우리가 지금 8월 29일부터 8월 31일까지 사용할 수 있는 KFC 쿠폰의 사용 여부를 판단할 때 보통 우리는 다음과 같이 할 것이다.
 public Class Coupon{
    public boolean isExpire(){
      Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
      gmtCal.set(2016,Calendar.AUGUST,29,0,0,0);
      Date startTime = gmtCal.getTime();
      gmtCal.set(2016,Calendar.SEPTEMBER,1,0,0,0);     
      Date endTime = gmtCal.getTime();
      Date now = new Date();
      return now.compareTo(startTime) >= 0 &&
             now.compareTo(endTime) < 0; 
    }
 }

이 경우, isExpire를 호출할 때마다 Calendar, TimeZone, 세 개의 Date 대상을 만들어야 하는데, 그 중에서 now Date를 제외하고는 모두 값이 변하지 않는다.이렇게 해서 매번 3개의 대상을 더 만들었다.권장 사용법
public Class Coupon{
   private static final Date START_TIME;
   private static final Date END_TIME;
   // , 。
   Static{
       Calendar gmtCal =  Calendar.getInstance(TimeZone.getTimeZone("GMT"));
     gmtCal.set(2016,Calendar.AUGUST,29,0,0,0);
     startTime = gmtCal.getTime();
     gmtCal.set(2016,Calendar.SEPTEMBER,1,0,0,0);     
     endTime = gmtCal.getTime();
   }   
   public boolean isExpire(){    
     Date now = new Date();
     return now.compareTo(startTime) >= 0 &&
            now.compareTo(endTime) < 0; 
   }
}

개선된 쿠폰 클래스는 isExpire를 호출할 때마다 Calendar, TimeZone, 두 개의 Date 대상을 만드는 것이 아니라 초기화할 때만 만들 수 있습니다.
자바에는 이 방면의 전형적인 응용이 많다.예를 들어 Map 인터페이스의 키셋 방법은 이 Map 대상의 키(key)를 포함하는 키셋 보기로 나뉜다.실제로 키셋을 호출할 때마다 같은 키셋의 실례를 되돌려줍니다. 그 중 하나가 되돌아오는 대상이 변할 때 다른 되돌아오는 대상은 같은 대상에 대한 인용이기 때문에 변화가 발생할 수 있습니다.
또한 JDK 1.5에는 추가 객체를 작성하는 새로운 방법인 자동 포장이 있습니다.Example: Integer int 아래에 자동 포장 오류의 예가 있는 기본 유형 및 객체 변환을 허용합니다.
public static void main(String[] args){
    Long sum = 0L;
    for( long i - 0 ; i < Integer.MAX_VALUE; i++){
        sum += i;
    }
 }

sum은 롱 유형을 사용하기 때문에 매번 계산할 때마다 i는 롱으로 롱을 포장하여 롱으로 만든다. 그러면 N 개의 롱 대상을 만들고 계산하기 때문에 속도가 자연히 많이 느려진다.sum의 유형을 롱에서 롱으로 전환함으로써 책에서 제시한 데이터는 실행 시 43초에서 6.8초로 낮아진다.따라서 포장류가 아닌 기본 유형을 우선적으로 사용하고 무의식적인 자동 포장에 주의해야 한다.

총결산


'대상을 만드는 대가가 매우 비싸다. 우리는 가능한 한 대상을 만들지 않는다.' 라고 착각하지 마라. 반대로 작은 대상의 구조기는 아주 적은 양의 디스플레이 작업만 한다.그래서 작은 대상의 창설과 회수는 매우 저렴하다. 특히 현대 JVM에서는 더욱 그렇다(JVM이 끊임없이 최적화되기 때문이다).추가 대상을 만들어 프로그램의 명확성과 간결성, 기능성을 향상시키는 것은 보통 좋은 일이다.
반대로 자신의 대상 탱크를 유지함으로써 대상을 만드는 것을 피하는 것은 좋은 방법이 아니다. 탱크의 대상이 매우 무거운 중량급 대상의 전형적인 것이 바로 데이터베이스 연결 대상이기 때문에 데이터베이스 연결 탱크가 생기지 않는다(데이터베이스 연결을 구축하는 대가가 매우 비싸기 때문에 이런 대상을 다시 사용하는 것은 매우 의미가 있다).그러나 일반적으로 자신의 대상 탱크를 유지하는 것은 코드를 어지럽히는 동시에 메모리의 점용을 증가시키고 성능을 손상시킬 수 있다.현대 JVM은 경량 개체 풀의 성능을 능가하기 쉽도록 최적화된 스팸 수거기를 구현합니다.
한 마디로 하면 불변류와 가변적이지만 일단 만들어지면 변하지 않는 대상에 대해서는 다시 대상을 사용할 수 있다.다른 상황에서 중량급 대상에 대해서는 중용을 고려할 수 있고 다른 대상에 대해서는 유연하게 창설해야 한다. 유지 대상 탱크 때문에 새로운 대상을 창설하는 데 추가 부담을 주지 않고 얻는 것보다 잃는 것이 많다.

좋은 웹페이지 즐겨찾기