1) String, StringBuffer, StringBuilder의 차이점과 쓰임새가 궁금해요. 그리고 성능은 어떤게 좋을까요?
2) String 은 immutable (한국말로는 뭔지..) 해서 성능이 좋지 않다라는 말도 있었는데요. 이 말 뜻은 뭔가요? 그리고 지금도 여전히 그런가요?
- 어디가 질문란인지 몰라서 남겼는데, 적당한 자리로 옮겨 주세요. 죄송합니다.
1) String, StringBuffer, StringBuilder의 차이점과 쓰임새가 궁금해요. 그리고 성능은 어떤게 좋을까요?
2) String 은 immutable (한국말로는 뭔지..) 해서 성능이 좋지 않다라는 말도 있었는데요. 이 말 뜻은 뭔가요? 그리고 지금도 여전히 그런가요?
0개의 의견 from FB
1) String, StringBuffer, StringBuilder의 차이점과 쓰임새가 궁금해요. 그리고 성능은 어떤게 좋을까요? 답변은 앞의 @changhwa.oh 님이 설명해 주셨는데요. 저는 좀 더 구체적으로 설명해 볼께요. 일단 String과 StringBuffer, StringBuilder 둘을 비교할 수 있는데요. String은 문자열을 대표하는 것으로 문자열을 조작하는 경우 유용하게 사용할 수 있고요. 문자열, 숫자, char 등을 concat할 때는 StringBuffer, StringBuilder를 사용할 수 있어요. 단, 복잡한 경우 의미가 있고, 단순한 경우에는 굳이 StringBuffer, StringBuilder를 쓰지 않고 "abc" + 1 + 'd'와 같이 +를 활용해 직접 합쳐도 됩니다.
StringBuffer, StringBuilder는 동기화 지원 여부입니다. 두 클래스가 제공하는 메소드는 같아요. 단, 메소드를 보면 StringBuffer는 각 메소드 별로 synchronized keyword가 존재하죠. 즉, 멀티 쓰레드 상태에서 동기화를 지원한다는 것이 다릅니다. 코드를 보면 다음과 같아요.
문자열을 +를 활용해 합치는 경우 정확히 어느 버전까지인지 모르겠는데요. 매번 String 인스턴스를 생성하는 방식이였어요. 그래서 성능상의 이슈가 많았죠. 이런 성능 이슈를 개선하기 위해 JDK 1.5 (@changhwa.oh 설명에 따르면) 버전 이후에는 컴파일 단계에서 StringBuilder로 컴파일 되도록 변경되었어요. 그래서 JDK 1.5 이후부터는 +를 활용해도 성능상에 큰 이슈는 없습니다.
이 내용을 좀 더 구체적으로 파고 들어 보면 다음과 같아요.
위 소스 코드를 컴파일 된 바이트 코드 결과물을 확인해 보면 다음과 같이 변경됩니다.
결과적으로 StringBuilder로 변환되는 것을 알 수 있어요. 최근 JDK 버전에서는 굳이 StringBuilder를 쓰지 않아도 되는거죠.
2) String 은 immutable (한국말로는 뭔지..) 해서 성능이 좋지 않다라는 말도 있었는데요. 이 말 뜻은 뭔가요? 그리고 지금도 여전히 그런가요? immutable에 대한 설명은 http://fowler.egloos.com/1243657 문서에 잘 정리되어 있네요. 앞의 질문에 대한 답변에서 설명했듯이 String이 immutable인 것은 변함이 없어요. 단, String을 concat할 때 String 인스턴스를 사용하는 것이 아니라 StringBuilder를 활용함으로써 성능 이슈를 해결했다고 보면 됩니다.
9개의 의견 from SLiPP
StringBuffer와 StringBuilder는 동기화 지원 여부 입니다.
단순히 성능만으로 놓고 보면 예전에 책을보면 연산이 많은 경우(?) String < StringBuffer < StringBuilder라고 봤습니다.
1) String, StringBuffer, StringBuilder의 차이점과 쓰임새가 궁금해요. 그리고 성능은 어떤게 좋을까요? 답변은 앞의 @changhwa.oh 님이 설명해 주셨는데요. 저는 좀 더 구체적으로 설명해 볼께요. 일단 String과 StringBuffer, StringBuilder 둘을 비교할 수 있는데요. String은 문자열을 대표하는 것으로 문자열을 조작하는 경우 유용하게 사용할 수 있고요. 문자열, 숫자, char 등을 concat할 때는 StringBuffer, StringBuilder를 사용할 수 있어요. 단, 복잡한 경우 의미가 있고, 단순한 경우에는 굳이 StringBuffer, StringBuilder를 쓰지 않고 "abc" + 1 + 'd'와 같이 +를 활용해 직접 합쳐도 됩니다.
StringBuffer, StringBuilder는 동기화 지원 여부입니다. 두 클래스가 제공하는 메소드는 같아요. 단, 메소드를 보면 StringBuffer는 각 메소드 별로 synchronized keyword가 존재하죠. 즉, 멀티 쓰레드 상태에서 동기화를 지원한다는 것이 다릅니다. 코드를 보면 다음과 같아요.
문자열을 +를 활용해 합치는 경우 정확히 어느 버전까지인지 모르겠는데요. 매번 String 인스턴스를 생성하는 방식이였어요. 그래서 성능상의 이슈가 많았죠. 이런 성능 이슈를 개선하기 위해 JDK 1.5 (@changhwa.oh 설명에 따르면) 버전 이후에는 컴파일 단계에서 StringBuilder로 컴파일 되도록 변경되었어요. 그래서 JDK 1.5 이후부터는 +를 활용해도 성능상에 큰 이슈는 없습니다.
이 내용을 좀 더 구체적으로 파고 들어 보면 다음과 같아요.
위 소스 코드를 컴파일 된 바이트 코드 결과물을 확인해 보면 다음과 같이 변경됩니다.
결과적으로 StringBuilder로 변환되는 것을 알 수 있어요. 최근 JDK 버전에서는 굳이 StringBuilder를 쓰지 않아도 되는거죠.
2) String 은 immutable (한국말로는 뭔지..) 해서 성능이 좋지 않다라는 말도 있었는데요. 이 말 뜻은 뭔가요? 그리고 지금도 여전히 그런가요? immutable에 대한 설명은 http://fowler.egloos.com/1243657 문서에 잘 정리되어 있네요. 앞의 질문에 대한 답변에서 설명했듯이 String이 immutable인 것은 변함이 없어요. 단, String을 concat할 때 String 인스턴스를 사용하는 것이 아니라 StringBuilder를 활용함으로써 성능 이슈를 해결했다고 보면 됩니다.
String 클래스는 jdk 1.5 버전이전에서도 (StringBuilder이 나오기 전) StringBuffer를 사용하도록 내부구조가 되어있었음.
String 클래스는 immutable => im + mutable 부정을 뜻하는 접두어에 mutate + able (변화 가능한)의 뜻이므로 변할 수 없는 => 불변이라는 말이 됨.
String 클래스의 객체는 Heap 상에 생성될 경우 한번 생성된 객체의 내부 내용을 변화시킬 수 없다는 뜻.
StringBuffer나 StringBuilder는 초기에 생성할 때 Buffer Size를 주도록 구성되며 이에 의한 생성, 확장 오버로드가 걸리기 때문에 의외로 Buffer Size를 잘못 지정할 경우 성능이 떨어질 가능성도 있음.
String 클래스의 경우 new 에 의한 생성이 아닐 때 초기 컴파일러 분석단계에서 literal 처리에 의해 최적화가 될 수 있기 때문에 오히려 빠른 결과를 보여줄 때가 있음.
그냥 생각나는 대로 주절 주절 해본건데... 박재성 교수도 익히 잘 알고 있는 사항일것으로 판단해보네 ㅋ
[Java 5에서 String Concatenation과 StringBuffer의 속도 비교]
http://www.mimul.com/pebble/default/2008/09/28/1222607880000.html
[Java Tips - String, StringBuffer, StringBuilder 선택 기준]
http://www.mimul.com/pebble/default/2007/11/26/1196088660000.html
조금이라도 도움이 될까해서 링크 걸어봅니다. 2007년 기준이니깐 지금도 유효한지 모르겠네요. JDK1.6 이상이 어떻게 바뀌었을지에 따라서 성능이나 이런 부분에 차이가 있을 것 같습니다.
위 글들을 읽고 직접 실험을 해 봤습니다. (1) String에 += 'a'; 를 반복 (2) StringBuffer로 같은 실험
제 시스템(우분투 14.04 - JDK7 기준) 에서는 여전히 StringBuffer가 String보다 매우 빨랐습니다. 예상한 결과와는 다르게 나왔네요.
@호수 http://www.mimul.com/pebble/default/2008/09/28/1222607880000.html 문서를 보면 다른 결과가 나오기도 합니다.
저도 이 참에 직접 실험해봐야겠네요. 역시 눈으로 직접 확인해야 하는 것인가요?
문자열 최적화라는 것 때문에 다른 결과라고 착각을 하게 만든 것입니다. 컴파일되었을 때
구문은
과 같게 됩니다.
@자바지기 한참 지난 글이지만... 해당 포스트를 보고 의문점이 생겨 테스트를 해보았습니다.
실무에서 런타임에 문자열이 조합되는 경우도 자주 발생하는 케이스같은데...
런타임의 경우에는 + 연산자의 연산속도가 현저하게 느려짐을 확인하였습니다.
http://blog.naver.com/freeofspace/220823372682확인을 안했으면.. 앞으로 + 연산자만 사용하다가 사고를 칠수도 있었을 것 같습니다.
혹시 저의 테스트 코드에 문제가 있으시면 알려주십시오.
capacity
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.