Skip to content

Latest commit

 

History

History
148 lines (98 loc) · 4.18 KB

6_불필요한_객체_생성을_피하라_신선영.md

File metadata and controls

148 lines (98 loc) · 4.18 KB

item 6. 불필요한 객체 생성을 피하라

✍ 객체의 재사용

같은 기능을 하는 객체를 여러 번 사용하는 것 보다 객체 하나를 재사용 하는 것이 더 나을 때가 있다.

String Pool 사용

String s1 = new String("java");
String s2 = new String("java");

System.out.println(s1 == s2); // false

String s3 = "java";
String s4 = "java";

System.out.println(s3 == s4); // true

s1, s2의 생성 방법은 java라는 문자열을 매번 새로 생성하지만,

s3, s4는 **String Constant Pool**을 사용하여 java라는 문자열을 캐싱하여 사용한다.

정적 팩터리 메서드사용

Wrapper Class에서는 캐싱을 지원해주는 valueOf()라는 메소드가 존재한다.

대표적으로 자주 사용하는 Boolean의 경우에는 true/false를,

Short, IntegerLong의 경우에는 -128 ~ 127까지의 수의 캐싱을 지원해준다.

Integer i1 = new Integer(50);
Integer i2 = new Integer(50);

System.out.println(i1 == i2); // false

Integer i3 = Integer.valueOf(50);
Integer i4 = Integer.valueOf(50);

System.out.println(i3 == i4); // true

하지만 img

Integer i5 = 50;
Integer i6 = 50;

1.8에서는 굳이 valueOf()를 추가할 필요가 없다. 😅


🎢 직접 캐싱하기

생성 비용이 비싼 객체 캐싱

생성 비용이 비싼 객체?

  • 크기가 아주 큰 Array
  • Database Connection
  • I/O 작업을 필요로 하는 Object
  • (책에 나오는) Pattern
public class Caching {

  private static int[] cachingArray = new int[500000];

  public static void main(String[] args) {
    long beforeTime = System.currentTimeMillis();

    // 1. 캐싱을 했을 때
    for (int i = 0; i < 200000; i++) {
      cachingArray[i] = 1;
    }
    System.out.println("캐싱 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000);

    // 2. 캐싱을 하지 않았을 때
    beforeTime = System.currentTimeMillis();

    for (int i = 0; i < 200000; i++) {
      int[] nonCachingArray = new int[500000];
      nonCachingArray[i] = 1;
    }
    System.out.println("캐싱 안 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000);
  }
}

img

하지만 가벼운 객체는 그냥 만드는게 낫다. 오히려 객체를 캐싱하려다가 코드를 헷갈리게 하고 메모리 사용량을 늘려 성능을 떨어뜨리는 경우도 발생하게 된다.


💣 불필요한 객체 만들지 않기

auto-boxing

Reference type - Primitive type 간 상호 변환해주는 기술

Integer a = 1;
int b = a + 2; // a를 int로 변환해준다.

하지만 오토박싱에도 변환 비용이 들기 때문에 의도하지 않은 오토박싱이 숨어들지 않게 주의해야한다.

public class AutoBoxing {
  public static void main(String[] args) {
    long beforeTime = System.currentTimeMillis();

    // 1. auto-boxing 사용 O
    Long sum = 0L;
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
      sum += i;
    }
    System.out.println("auto-boxing 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000.0);

    // 2. auto-boxing 사용 X
    beforeTime = System.currentTimeMillis();
    long sum2 = 0L;
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
      sum2 += i;
    }
    System.out.println("auto-boxing 안 했을 때 소요시간(s) : " + (System.currentTimeMillis() - beforeTime) / 1000.0);
  }
}

img


🐇 맺으며

객체 생성은 비싸니 피해야한다 (X)

생성 비용이 비싼 객체의 재사용을 고려해보자 (O)