String s = new String("java"); //해당 코드는 실행 될 때마다 String 인스턴스를 새로 만듬, Heap 영역에 존재
String s ="java"; //해당 코드는 하나의 String 인스턴스를 사용, String constant pool에서 검색해 재사용
Boolean(String); //deprecated, 권장되지 않는 코드
Boolean.valueOf(String) //권장되는 코드
// 코드 6-1 성능을 훨씬 더 끌어올릴 수 있다!
static boolean isRomanNumeralSlow(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}
- Pattern은 입력받은 정규표현식에 해당하는 유한 상태 머신(finite state machine)을 만들기 떄문에 인스턴스 생성 비용이 높다.
- 유한 상태 머신(finite state machine) : 유한한 개수의 상태를 가질 수 있는 추상 기계
// 코드 6-2 값비싼 객체를 재사용해 성능을 개선한다.
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumeralFast(String s) {
return ROMAN.matcher(s).matches();
}
그 후 메서드가 호출될 때마다 해당 인스턴스를 재사용한다.
- 뒷단 객체 하나당 어댑터 하나씩
Map<String, Object> map = new HashMap<>();
map.put("java", "effective")
//set1, set2 는 같은 인스턴스
Set<String> set1 = map.keySet();
Set<String> set2 = map.keySet();
private static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++)
sum += i; // 불필요한 Long 객체 생성
return sum;
}
- 객체 풀 만들는 게 나은 예: DB 연결
JVM의 가비지 컬렉터는 상당히 최적화되어 있어서 직접 만든 객체 풀보다 빠르다.
Reference: