레이블이 StringBuffer인 게시물을 표시합니다. 모든 게시물 표시
레이블이 StringBuffer인 게시물을 표시합니다. 모든 게시물 표시

2015년 7월 15일 수요일

자바(JAVA)의 문자열 객체 String, StringBuilder, StringBuffer 비교


 자바에서 문자열을 저장하는데 사용되는 객체는 String, StringBuilder, StringBuffer 세 가지가 있다. 보통 문자열을 저장하는데 String 객체를 사용하지만 문자열을 빈번하게 수정할 필요가 있는 경우 String 객체보다는 StringBuilder 객체가 성능면에서 더 유리하다.

[표 1] 문자열 저장 객체간 비교
클래스명
특징
성능
메모리
String
불변하는 문자열 저장시 주로 사용

가장 낮다.
StringBuilder
수시로 가변하는  문자열 저장시 주로 사용
가장 높다.

StrungBuffer
다른 쓰레드 간 동기화가 필요한 경우 StringBuilder대신 사용



가변하는 문자열을 다루는데 있어서의 속도를 알아보기 위해서 다음과 같은 간단한 벤치마크 프로그램을 실행해 보았다. (JDK8 이용)


package tut_20;
import static java.lang.System.nanoTime;
public class Tut_20 {
 public static void main(String[] args) {
     long ls, le;
     long iter = 100000;

     ls = nanoTime();
     String str = "";
     for (int k = 0; k < iter; k++) {
         str += 'a';
     }
  System.out.println("String       :"+(nanoTime()-ls)/1e9+ "sec.");
       
       ls = nanoTime();
       StringBuilder strb = new StringBuilder();
       for (int k = 0; k < iter; k++) {
           strb.append('a');
       }
 System.out.println("StringBuilder:"+(nanoTime()-ls)/1e9+ "sec.");
       
       ls = nanoTime();
       StringBuffer strbf = new StringBuffer();
       for (int k = 0; k < iter; k++) {
           strbf.append('a');
       }
 System.out.println("StringBuffer :"+(nanoTime()-ls)/1e9+ "sec.");     
   }
}
실행 결과
String       :4.884195203sec.
StringBuilder:0.001943612sec.
StringBuffer :0.0015706sec.

결과는 보다시피 StringBuilder가 가장 빨랐고 StingBuilder 와 StringBuffer 는 차이가 별로 나지 않았다. (JDK5 이상에서는 String 객체도 수정이 일어날 때 내부적으로 StringBuffer로 변환되어 사용된다고 알고 있었는데 좀 의외다.)

 다음으로 문자열 내에서 검색하는 속도를 마찬가지로 간단한 프로그램을 실행하여 측정해 보았다. (JDK8 사용)

package tut_20;
import static java.lang.System.nanoTime;
import java.util.Random;

public class Tut_20 {
   public static void main(String[] args) {
       long ls, le;
       long iter = 100000000;

       String str = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG";
       int len = str.length();
       char ch;
       Random rand = new Random();

       ls = nanoTime();
       for (int k = 0; k < iter; k++) {
           ch = str.charAt(rand.nextInt(len));
       }
 System.out.println("String       :"+(nanoTime()-ls)/1e9+ "sec.");
       
       StringBuilder strb = new StringBuilder(str);
       ls = nanoTime();
       for (int k = 0; k < iter; k++) {
           ch = strb.charAt(rand.nextInt(len));
       }
 System.out.println("StringBuilder:"+(nanoTime()-ls)/1e9+ "sec.");
       
       StringBuffer strbf = new StringBuffer(str);
       ls = nanoTime();
       for (int k = 0; k < iter; k++) {
           ch = strbf.charAt(rand.nextInt(len));
       }
 System.out.println("StringBuffer :"+(nanoTime()-ls)/1e9+ "sec.");
   }
}
실행 시간
String       :1.258389526sec.
StringBuilder:1.414282314sec.
StringBuffer :3.205902914sec.

결과에서 나타났듯이 String 이 근소하게 StringBuilder 에 비해서 빨랐다.

 따라서 다음과 같이 정리해 볼 수 있겠다.

  1. 수정될 필요가 없는 문자열은 String 객체로 사용한다.
  2. 빈번에게 수정되는 문자열을 다룰 때는 StringBuilder 객체를 사용한다.
  3. 빈번에게 수정될 뿐만 아니라 서로 다른 쓰레드간 동기화를 시켜야 할 경우에는 StringBuffer를 사용한다.