티스토리 뷰

 

1. String

자바에서 사용되는 String의 가장 큰 특징은 불변이라는 것이다. String 객체가 한번 생성되면 그 객체는 더 이상 수정할 수 없다.

 

String 객체를 생성하는 방법은 아래와 같다.

String str = "ABC";
// or 
String str = new String("ABC");

앞서 언급한 것처럼 불변이기 때문에, 멀티쓰레드 환경에서 데이터 불일치에 대한 우려가 없기 때문에 사용하기 적합하다.

 

다만, 수정이 필요한 새 String을 생성해야 한다는 불편함도 있다. 때문에, 큰 문자열로 작업하거나 많은 수정을 수행할 때 비효율적으로 동작하게 된다.

 

2. StringBuffer

Java 1.4까지는 문자열을 다루기위해서 StringBuffer가 유일한 방법이었다고 한다.

 

StringBuffer의 public method가 synchronized 하기 때문에, 이에 대해 별도의 cost가 필요하다는 단점이 있다.

 

때문에 멀티 쓰레드 환경에서 안전하게 동작하지만, 일반적인 문자열 처리 과정에서는 불필요한 자원소모가 발생한다는 단점이 있다.

 

StringBuffer는 String과 다르게 수정이 가능하며, append, insert, replace, delete와 같은 공용 매서드를 제공한다.

 

아래와 같이 선언하고 수정할 수 있다.

StringBuffer sb = new StringBuffer("Hello");
sb.append("World"); // modifies the existing StringBuilder object

3. StringBuilder

Java 1.5부터 단일 쓰레드에서 thread safety한 기능이 필요하지 않을 때가 많기 때문에 StringBuilder라는 별도의 클래스가 생겼다.

 

StringBuffer에서 제공하는 대부분의 매서드들을 제공하고, 일반적인 개발에서 멀티 쓰레드 환경을 사용하는 경우가 드물기 때문에 StringBuilder가 일반 프로그래밍 시나리오에서 StringBuffer보다 더 적합하다.

 

StringBuilder도 아래와 같이 선언하고 수정할 수 있다.

StringBuilder sb = new StringBuilder("Hello");
sb.append("World"); // modifies the existing StringBuilder object

 

아래는 StringBuffer와 StringBuilder의 성능 비교 표이다.

 

멀티쓰레드가 아닌 일반 반복문을 실행한 결과이고, 이 환경에서는 StringBuilder가 10~20% 더 좋은 성능을 보인다는 걸 확인할 수 있다.

 

(참고) 문자열 결합 시 주의할 점

일반적으로 자바에서 String을 합치기 위해서 가장 많이 사용하는 방법은 "+" 연산자를 이용해  이어붙이는 것이다.

 

"+" 연산자를 이용해 String을 이어 붙이는 것은 StringBuilder의 객체를 매번 만들어 주는 방식과 유사하다. 매번 String 객체를 생성해주기 때문에 리소스를 많이 잡아먹게 된다.

 

String s = "";
for (int i = 0; i < 1000; i++) {
    s += "hello";
}

///////////////////////////////////////////////////

StringBuilder concat = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    StringBuilder sb = new StringBuilder("hello");
    concat.append(sb);
}
String s = concat.toString();

위의 예시를 보면, 반복문 내에서 StringBuilder 객체가 천번 재생성된다. 

 

String을 사용했을 때는 수정이 불가하기 때문에 위와 같이 사용할 수 밖에 없다.

 

하지만 StringBuilder를 적절히 활용한다면, 아래와 같이 수정해 효율적으로 자원을 사용할 수 있다.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    concat.append(sb);
}
String s = sb.toString();

 

StringBuilder는 수정이 가능하기 때문에 한번의 객체 생성으로 같은 결과를 얻을 수 있다.

 

아래의 표를 참고하면 좋을 것 같다. 특정 문자열을 5만번 결합하는 반복문을  21번 시행한 결과라고 한다.

 

문자열을 합칠 때, "+" 연산자를 활용한 String 보다 StringBuilder/StringBuffer를 사용했을 때 압도적인 성능향상을 얻을 수 있다.

 

다만, 문자열 결합의 반복 횟수가 적을 경우 "+" 연산자로 결합하는것을 생각해보는게 좋다.

 

클린코드 책에서도 이야기한 내용이지만, 성능보다는 좋은 가독성을 제공하기 때문이다.

 

가독성과 성능은 반비례하는 경우가 많은데 문자열 결합이, 그런 상황이니 상황에 맞춰 개발하라고 말할 수 밖에 없다...

마치며

사실 문자열 결합에 관해서 생각해보면서 작성한 글이다. 문자열 결합의 횟수가 많다면 StringBuilder를 사용하도록 하자.


참고 사이트

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함