String / StringBuffer / StringBuilder
간단한 성능비교 테스트.
package test;
public class StringTest {
int test = 99999;
public static void main(String[] args) {
StringTest stringTest = new StringTest();
System.out.println("스트링: " + stringTest.stringTest());
System.out.println("스트링빌더: " + stringTest.stringbuilderTest());
System.out.println("스트링버퍼: " + stringTest.stringbufferTest());
}
public long stringTest() {
String a = "test";
long start = System.currentTimeMillis();
for(int i =0; i<test; i++) {
a+="test";
}
long end = System.currentTimeMillis();
return end-start;
}
public long stringbuilderTest() {
StringBuilder sb = new StringBuilder("test");
long start = System.currentTimeMillis();
for(int i =0; i<test; i++) {
sb.append("test");
}
long end = System.currentTimeMillis();
return end-start;
}
public long stringbufferTest() {
StringBuffer sb = new StringBuffer("test");
long start = System.currentTimeMillis();
for(int i =0; i<test; i++) {
sb.append("test");
}
long end = System.currentTimeMillis();
return end-start;
}
}
결과 :
스트링: 6674
스트링빌더: 3
스트링버퍼: 4
StringBuffer의 append 메소드에 들어가보면
synchronized 키워드가 붙어 있어 동기화를 지원하는 것을 확인할 수 있다.
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
StringBuilder의 append 메소드 : 동기화를 지원하지 않는 대신 StringBuffer보다 조금 더 빠르다.
public StringBuilder append(String str) {
super.append(str);
return this;
}
String 클래스 뜯어보기 :
단순 String a에 String b 를 더하기했다.
public class test {
public class Concat {
String plus(String a, String b) {
a += b;
return a;
}
}
}
javap -c 로 해체결과:
즉 a+=b 는
a = new StringBuilder()
.append(a)
.append(b)
.toString();
와 같이 동작함을 알 수 있다.
그럼 세개를 한번에 +하면 어떻게 될까?
package test;
public class test {
String plus(String a, String b, String c) {
String d = a+b+c;
return d;
}
}
javap -c 로 해체결과:
a+=b와 같이 처음 한 번만 StringBuilder 객체를 생성하고 append()메소드를 사용 후 toString으로 변환해 리턴하는 것을 볼 수 있다.
a+b+c 와 같이 한 번의 연산이 아니라 각각의 줄에서 문자열을 붙이면 어떻게 될까?
public class test {
String plus(String a, String b) {
a+=b;
a+="1";
a+="2";
return a;
}
}
javap -c 로 해체결과:
줄마다 StringBuilder 객체가 각각 생성되어 3번의 객체가 생성됨을 볼 수 있다.
마지막으로 문자열을 붙이는 String의 concat() 메소드에 들어가보니
public String concat(String str) {
int olen = str.length();
if (olen == 0) {
return this;
}
if (coder() == str.coder()) {
byte[] val = this.value;
byte[] oval = str.value;
int len = val.length + oval.length;
byte[] buf = Arrays.copyOf(val, len);
System.arraycopy(oval, 0, buf, val.length, oval.length);
return new String(buf, coder);
}
int len = length();
byte[] buf = StringUTF16.newBytesFor(len + olen);
getBytes(buf, 0, UTF16);
str.getBytes(buf, len, UTF16);
return new String(buf, UTF16);
}
역시 새로운 String 객체를 생성해 리턴한다.
그러나 직접 해보니 concat()이 + 보다는 조금 더 빠른 것을 확인할 수 있었다.