티스토리 뷰
JDK 1.5 버전 이후부터, String
의 +
연산은 컴파일시에 StringBuilder
를 사용하도록 자동변환되어 성능 최적화가 이뤄진다고 알려져 있습니다. 그러나 String은 항상 StringBuilder로 변환되지 않습니다.
String
연산을 수행하는 몇가지의 예제를 준비했습니다. String
을 연산하는 소스코드를 컴파일하고, 다시 디컴파일
하여 성능최적화가 이뤄졌는지 확인해보겠습니다. (디컴파일러는 JAD를 사용하였으며, 예제코드들은 "012"라는 문자열을 이어붙여서 만드는 작업을 수행합니다.)
예제1) 한줄로 모두 선언한 경우
//컴파일 전 소스파일
String str1 = "0" + "1" + "2";
//컴파일 이 후, 디컴파일 한 소스파일
String str1 = "012";
한줄로 모두 선언한 경우는 하나의 String
으로 변환 되었습니다. 결론적으로 성능최적화가 되었습니다. 따라서 이런 경우에 굳이 StringBuilder나 StringBuffer를 사용할 필요가 없습니다.
예제2) 여러줄로 선언한 경우
//컴파일 전 소스파일
String str2 = "";
str2 += 0;
str2 += 1;
str2 += 2;
//컴파일 이 후, 디컴파일 한 소스파일
String str2 = "";
str2 = (new StringBuilder()).append(s1).append("0").toString();
str2 = (new StringBuilder()).append(s1).append("1").toString();
str2 = (new StringBuilder()).append(s1).append("2").toString();
String
연산을 여러줄에 걸처 선언한 경우는 매 연산시마다 새로운 StringBuilder
를 선언하고 있습니다. (StringBuilder
를 사용하더라도) 매 연산시마다 새로운 객체를 생성하고 있으니 성능저하가 발생하게 됩니다. 따라서 이런 경우에는 StringBuilder 혹은 StringBuffer를 사용하여 성능최적화를 해야합니다.
예제3) 반복문 안에서 선언한 경우
//컴파일 전 소스파일
String str3 = "";
for (int i = 0; i < 3; i++) {
str3 += i;
}
//컴파일 이 후, 디컴파일 한 소스파일
String str3 = "";
for(int i = 0; i < 3; i++) {
str3 = (new StringBuilder()).append(s2).append(i).toString();
}
반복문안에서 연산을 수행하는 경우도 반복수행시마다 새로운 StringBuilder
를 생성하고 있으니 성능저하가 발생하게 됩니다. 따라서 이런 경우에는 StringBuilder 혹은 StringBuffer를 사용하여 성능최적화를 해야합니다.
예제4) String의 concat() 메서드를 사용하여 선언한 경우
//컴파일 전 소스파일
String str4 = ""
.concat("0")
.concat("1")
.concat("2");
//컴파일 이 후, 디컴파일 한 소스파일
String str4 = "".concat("0").concat("1").concat("2");
한줄로 선언하더라도 concat()
메서드를 사용한 경우는 StringBuilder
로 변환되지 않습니다. 성능저하가 발생하게 됩니다. 따라서 이런 경우에는 StringBuilder 혹은 StringBuffer를 사용하여 성능최적화를 해야합니다.
결론
String
연산은 +를 사용하여 한줄로 선언하는 경우에만 성능저하가 발생하지 않는다. 여러줄에 걸쳐서 연산해야하는 경우는 명시적으로 StringBuilder
를 사용해야 한다.
'Java' 카테고리의 다른 글
왜 (x.compareTo(y) == 0) == (x.equals(y))를 만족해야 할까? (0) | 2020.11.08 |
---|---|
IntelliJ로 JUnit4 테스트 JUnit5로 변환하기 (2) | 2020.07.01 |
EnumSet이 new 연산자를 사용하지 않는 이유 (0) | 2019.09.12 |
Set은 왜 get() 메소드가 없을까? (0) | 2019.07.09 |
EnumMap(EnumSet) 쓰면 좋을까? (vs HashMap) (2) | 2019.06.06 |