본문 바로가기
Programming/Java * Spring

[Java] 06. String, StringBuilder 속도 비교

by 고막고막 2019. 3. 25.

String 클래스 변경 방법

String 클래스는 작은 문자의 변화에도 계속 새로 객체(인스턴스)를 생성하기 때문에 문자열의 변경이 불가능하다. 각각 다른 인스턴스이므로 변수간의 해시 값이 다른 것을 확인할 수 있다. 이런 작업이 빈번해지면 성능저하의 요인이 된다.

  • Append: 인덱스 끝에 삽입
  • Insert: 인덱스 중간에 삽입
String str1 = "Lemon";
String str2 = str1+'a'; // str1.concat('a')
String str3 = str2+'b';
String str4 = str3+"cd";

System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);

System.out.println("str1 해쉬 값: " + (str1.hashCode()));
System.out.println("str2 해쉬 값: " + (str2.hashCode()));
System.out.println("str3 해쉬 값: " + (str3.hashCode()));
System.out.println("str4 해쉬 값: " + (str4.hashCode()));


StringBuilder 클래스

StringBuilder 클래스는 문자열의 변경이 가능하다. 내부에 char 배열공간이 존재해 문자열의 크기가 늘어나면 자동으로 증가시켜주고, 배열이 꽉 차면 또 자동으로 늘려준다. 동일한 인스턴스에 덮어쓰므로 같은 해시 값을 가지기 때문에 효율성이 뛰어나다.

  • String Builder Class: Multi-Thread-safe
  • String Buffer Class: Thread-safe
StringBuilder strBuf = new StringBuilder("AB");

// append
strBuf.append(25);
System.out.println(strBuf);
System.out.println("해쉬 값: "+strBuf.hashCode());

// append의 클래스가 StringBuilder이므로 자기 자신에게 삽입
strBuf.append('Y').append(true);
System.out.println(strBuf);
System.out.println("해쉬 값: "+strBuf.hashCode());

// insert
strBuf.insert(2, false);
System.out.println(strBuf);
System.out.println("해쉬 값: "+strBuf.hashCode());

// append와 같은 기능을 insert로 표현
strBuf.insert(strBuf.length(), 'z'); 
System.out.println(strBuf);		
System.out.println("해쉬 값: "+strBuf.hashCode());



String 클래스 vs. StringBuilder 클래스 속도 비교

StringBuilder 클래스의 속도가 현저히 빠르기 때문에, Java Tuning에서는 첫번째로 String 클래스의 사용을 분석해서 보완한다.

// String 클래스의 속도 연산
public static long getStringSpeed() {
  String str = "A";
  String target = "B";
  long start = System.currentTimeMillis();
  for(int i=0;i<90000;i++)
    str += target;
  long end = System.currentTimeMillis();
  return end - start;
}

// StringBuilder 클래스의 속도 연산
public static long getStringBuilderSpeed() {
  StringBuilder str = new StringBuilder("A");
  String target = "B";
  long start = System.currentTimeMillis();
  for(int i=0;i<90000;i++)
    str.append(target);
  long end = System.currentTimeMillis();
  return end - start;
}

public static void main(String[] args) {
  long lSstrTime = getStringSpeed();
  long lSBTime = getStringBuilderSpeed();
  System.out.println("String 시간: "+lSstrTime);
  System.out.println("StringBuilder 시간: "+lSBTime);
}