효율적인 문자열 연결 방법
자바에서 문자열을 연결하는 방법을 살펴보고 각각의 효율성을 비교해 봅니다.
문자열을 연결하는 방법
1. + 연산자 이용
2. String 클레스의 concat 메소드 사용
3. StringBuffer의 append 사용
4. StringBuilder의 append 사용
네가지 경우에 대해 테스트를 작성합니다.
private String s1;
private String s2;
@Before
public void setUp(){
s1 = "Hibernate";
s2 = "Spring";
}
@Test
public void plusOperator() {
Long start = Calendar.getInstance().getTimeInMillis();
for(int i = 0 ; i < 5000 ; i++){
s1 = s1 + s2;
}
Long end = Calendar.getInstance().getTimeInMillis();
System.out.println("Operator : " + (end - start));
}
@Test
public void concatMethod() {
Long start = Calendar.getInstance().getTimeInMillis();
for(int i = 0 ; i < 5000 ; i++){
s1 = s1.concat(s2);
}
Long end = Calendar.getInstance().getTimeInMillis();
System.out.println("ConcatMethod : " + (end - start));
}
@Test
public void stringBuffer() {
Long start = Calendar.getInstance().getTimeInMillis();
StringBuffer buffer1 = new StringBuffer(s1);
StringBuffer buffer2 = new StringBuffer(s2);
for(int i = 0 ; i < 5000 ; i++){
buffer1.append(buffer2);
}
String result = buffer1.toString();
Long end = Calendar.getInstance().getTimeInMillis();
System.out.println("StringBuffer : " + (end - start));
}
@Test
public void stringBuilder() {
Long start = Calendar.getInstance().getTimeInMillis();
StringBuilder builder1 = new StringBuilder(s1);
StringBuilder builder2 = new StringBuilder(s2);
for(int i = 0 ; i < 5000 ; i++){
builder1.append(builder2);
}
String result = builder1.toString();
Long end = Calendar.getInstance().getTimeInMillis();
System.out.println("StringBuilder : " + (end - start));
}
}
결과는 다음과 같습니다.
ConcatMethod : 500
StringBuffer : 15
StringBuilder : 0
Operator : 1062
ConcatMethod : 438
StringBuffer : 0
StringBuilder : 15
Operator : 1532
ConcatMethod : 453
StringBuffer : 0
StringBuilder : 16
Operator : 1172
ConcatMethod : 453
StringBuffer : 0
StringBuilder : 16
Operator : 1281
ConcatMethod : 453
StringBuffer : 16
StringBuilder : 16
Operator : 1171
ConcatMethod : 500
StringBuffer : 0
StringBuilder : 0
Operator : 1187
ConcatMethod : 454
StringBuffer : 0
StringBuilder : 16
흠.. 이상하네요. 예전에 영회형이 간단하게 정리 했었던 글과 정반대의 결과가 나왔습니다.
테스트는 Java 6.0을 사용했습니다.
StringBuffer와 StringBuilder 가 String 클레스에 있는 concat 메소드나 연산자에 비해 엄청나게 빠른것을 확인할 수 있습니다.
원인은 String의 immutable한 특징 때문입니다. API를 보시면 concat 메소드에 다음과 같이 적혀 있습니다.
즉 매번 새로운 String 객체를 만들게 되기 때문에 추가적인 비용이 많이 발생하는 것 같습니다. 하지만 그렇다 하더라도.. + 연산자 사용하는 것 보단 훨씬 낳습니다.
s1 = s1 + s2; 라는 한 문장이 두 개의 연산(더하기 연산과 대입 연산)을 포함하고 있기 때문에 저런 결과가 나왔다고 생각됩니다. 그렇다고 s1 + s2; 이렇게 표현할 수도 없고(컴파일에러) 참 난감하네요. :)