String 보다는 StringBuilder, StringBuffer를 사용해야하는 이유.
이유는 간단하다.
String보다는 Stringbuilder 와 StringBuffer이 성능ㅇ ㅣ좋으므로..
1. StringBuilder와 StringBuffer을 사용시 append 를 이용할 때 하지 말 것
String str ="abcde";
String a = new String();
StringBuffer sb= new StringBuffer();
StringBuilder sbs = new StringBuilder();
long start = System.currentTimeMillis();
for(int i=0; i<90000; i++) {
a += str + "=" + str;
}
long end = System.currentTimeMillis();
System.out.println("String is :"+ (end-start)/1000.0 );
for(int i=0; i<10000000; i++) {
sb.append(str + "=" +str);
}
long end1 = System.currentTimeMillis();
System.out.println("StringBuffer is :"+ (end1-end)/1000.0 );
for(int i=0; i<10000000; i++) {
sb.append(str + "=" +str);
}
long end2 = System.currentTimeMillis();
System.out.println("StringBuilder is :"+ (end2-end1)/1000.0 );
결과
String is :44.821
StringBuffer is :0.94
StringBuilder is :0.762
이런식으로 append 안에 + 를붙여서 문자열을 연결하면 StringBuffer 의 사용효과가 전혀 없어진다.
그러므로 append() 메서드 안에 하나씩 문자열을 더한다.
ex)
sb.append("ABCD");
sb.append("=");
sb.append("EFG");
String str ="abcde";
String a = new String();
StringBuffer sb= new StringBuffer();
StringBuilder sbs = new StringBuilder();
long start = System.currentTimeMillis();
for(int i=0; i<90000; i++) {
a += str;
a += "=";
a += str;
}
long end = System.currentTimeMillis();
System.out.println("String is :"+ (end-start)/1000.0 );
for(int i=0; i<10000000; i++) {
sb.append(str);
sb.append("=");
sb.append(str);
}
long end1 = System.currentTimeMillis();
System.out.println("StringBuffer is :"+ (end1-end)/1000.0 );
for(int i=0; i<10000000; i++) {
sb.append(str);
sb.append("=");
sb.append(str);
}
long end2 = System.currentTimeMillis();
System.out.println("StringBuilder is :"+ (end2-end1)/1000.0 );
결과
String is :134.218
StringBuffer is :0.542
StringBuilder is :0.565
2. String
이 소스 라인이 수행되면 a에 str을 더하면 새로운 String 클래스 객체가 만들어지고, 이전에 있던 a 객체는 필요 없는 쓰레기 값이 되어 GC대상이 되어버린다.
for(int i=0; i<90000; i++) {
a += str;
}
a += str 값(첫번째수행) : abcde
a += str 값(두번째수행) : abcdeabcde
a += str 값(세번째수행) : abcdeabcdeabcde
주소=100 : abcde
주소=150 : abcde | abcde
주소=200 : abcde | abcde | abcde
가장 처음 a 객체는 abcde 값이 저장되어 있었다. 값이 더해지면서 기존의 a는 사라지고 새로운 주소 a(150) 이 생기고 abcde | abcde 라는 값이 생긴다.
이런 작업을 반복 수행되면서 메모리를 많이 사용하게 되고 응답속도에 많은 영향을 끼친다.
3. StringBuffer, StringBuilder
- StringBuffer, StringBuilder는 String과 다르게 새로운 객체를 생성하지 않고 기존에 있는 객체의 크기를 증가시키면서 값을 더한다.
for(int i=0; i<10000000; i++) {
sb.append(str);
}
sb.append(str) (첫번째수행) : abcde
sb.append(str) (첫번째수행) : abcdeabcde
sb.append(str) (첫번째수행) : abcdeabcdeabcde
주소=100 : abcde
주소=100 : abcde abcde
주소=100 : abcde abcde abcde
3. 그럼 어느 때 사용하는 것이 효율적인가?
String
- 짧은 문자열을 더할 경우 사용
StringBuilder
- 단일 스레드에서 안전성만을 보장한다.
- 스레드에 안전여부에 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋음
- 메서드 내에 변수를 선언했다면, 해당 변수는 그 메서드 내에서만 살아있으므로 이 클래스를 사용해야함
StringBuffer
- 스레드에 안전하게 설계되어 있으므로, 여러 개의 스레드에서 하나의 StringBUffer 객체를 처리해도 전혀 문제가 되지 않는다.
- 개발 중인 시스템이 스레드에 안전한지 모를경우 사용하면 좋음
- 클래스에 static으로 선언한 문자열을 변경하거나, singleton 으로 선언된 클래스에 선언된 문자열일 경우 이 클래스를 사용해야함
응답시간
String > StringBuffer > StringBuilder
메모리
String >StringBuffer == StringBuilder
'Language > Java' 카테고리의 다른 글
규칙 1. 생성자대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라 (0) | 2017.01.19 |
---|---|
[병렬처리]2. 스레드의 안전성 (0) | 2016.12.12 |
[링크]셧다운 후크를 사용한 어플리케이션의 안전한 종료 처리 (0) | 2016.08.11 |
Java static 키워드 (0) | 2016.08.11 |
java final 키워드 (0) | 2016.08.11 |