728x90
동일 객체 생생보다는 기존 객체 재사용
- 이 문장은 실행될 때마다 String 인스턴스를 새로 만든다.
- 생성자에 넘겨진 "bikini" 자체가 이 생성자로 만들어내려는 String과 기능적으로 완전히 똑같다.
- 이 문장이 반목문이나 빈번히 호출되는 메소드에 있다면 쓸데없는 String 인스턴스가 수백만 개 만들어질 수도 있다.
String s = new String("bikini");
- 이 코드는 새로운 인스턴스를 매번 만드는 대신 하나의 String 인스턴스를 사용한다.
- 나아가 JVM 안에서 똑같은 문자열 리터럴을 사용하는 모든 코드가 같은 객체를 재사용함이 보장된다.
String s = "bikini";
생성 비용이 아주 비싼 객체의 경우 캐싱하여 재사용을 권한다.
- 아래 케이스에서도
isRomanNumeralSlow메서드는 정규식 내용을 그 때마다 객체를 생성한다. isRomanNumeralFast는ROMAN이라는static으로 정의하여 객체를 재사용하여 리소스를 줄인다.- 정확히 말하면 GC의 제거 대상이 되지 않아 리소스를 줄이는 것이다.
public class RomanNumerals {
// 코드 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})$");
}
// 코드 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();
}
public static void main(String[] args) {
int numSets = Integer.parseInt(args[0]);
int numReps = Integer.parseInt(args[1]);
boolean b = false;
for (int i = 0; i < numSets; i++) {
long start = System.nanoTime();
for (int j = 0; j < numReps; j++) {
// 성능 차이를 확인하려면 xxxSlow 메서드를 xxxFast 메서드로 바꿔 실행해보자.
b ^= isRomanNumeralSlow("MCMLXXVI");
}
long end = System.nanoTime();
System.out.println(((end - start) / (1_000. * numReps)) + " μs.");
}
// VM이 최적화하지 못하게 막는 코드
if (!b)
System.out.println();
}
}
불필요한 객체를 만들어내는 또 다른 예는 오토박싱이다.
- 오토박싱은 기본 타입과 그에 대응하는 박싱된 기본 타입의 구분을 흐려주지만, 완전히 없애주는 것은 아니다.
Long으로 선언해서 불필요한Long인스턴스가 만들어진다.- 박싱된 기본 타입보다는 기본타입을 사용하고, 의도치 않은 오토박싱이 숨어들지 않도록 주의하자.
class Sum {
private static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++)
sum += i;
return sum;
}
public static void main(String[] args) {
int numSets = Integer.parseInt("3");
long x = 0;
for (int i = 0; i < numSets; i++) {
long start = System.nanoTime();
x += sum();
long end = System.nanoTime();
System.out.println((end - start) / 1_000_000. + " ms.");
}
// VM이 최적화하지 못하게 막는 코드
if (x == 42)
System.out.println();
}
}728x90
'Programming Language > Java' 카테고리의 다른 글
| [Java] 메모리 누수가 발생하는 케이스 (0) | 2024.05.03 |
|---|---|
| [이펙티브 자바]Item.07-다 쓴 객체 참조를 해제하라(+싱글톤) (0) | 2024.05.03 |
| [이펙티브 자바]Item.05-자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2024.04.05 |
| [이펙티브 자바]Item.04-인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2024.04.05 |
| [이펙티브 자바]Item.03-private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2024.04.02 |