이전에 찾은 자료를 올려 놓습니다. 작성자 : 최종명(jmchoi@it.soongsil.ac.kr)
String과 StringBuffer 성능 차이
글: 최종명(jmchoi@it.soongsil.ac.kr)
String은 내용을 변경할 수 없기 때문에 String에서 + 연산자를 사용하면 내부적으로StringBuffer를 생성해서 append() 메소드를 이용해서 문자열을 결합한다는 것은 대부분의 자바 프로그래머가 알고 있을 것입니다.
따라서 String을 많이 사용하는 서블릿이나 기타 프로그램에서는 되도록이면 StringBuffer나 char[]를 사용하시는 것이 효과적이라는 것도 다 알고 있는 사실입니다. 그런데 프로그램하다보면 귀찮아서라도 String을 많이 사용하는 것이 현실입니다.
그래서 잠시 10여분을 할애하여 String과 StringBuffer의 성능 차이를 테스트 해보았습니다.
테스트는 제가 새로 얻은(?) 펜티엄에 윈도우 2000이 설치된 컴퓨터 에서 했습니다. 테스트할 프로그램은 다음과 같습니다. 각 프로그램은 모두 "a" 문자열을 30,000번 씩 결합하도록 했습니다.
예제 : StringTime.java
1 public class StringTime {
2
3 public static void main(String args[]) {
4 Runtime rt = Runtime.getRuntime();
5 System.out.print(rt.freeMemory());
6 System.out.println("/" + rt.totalMemory());
7 long start = System.currentTimeMillis();
8 String a = "a";
9 for(int i=0; i < 30000; i++) {
10 a += "a";
11 }
12 long stop = System.currentTimeMillis();
13 System.out.println(stop - start);
14 System.out.print(rt.freeMemory());
15 System.out.println("/" + rt.totalMemory());
16 }
17
18 }
예제 : StringBuffer.java
1 public class StringBufferTime {
2
3 public static void main(String args[]) {
4 Runtime rt = Runtime.getRuntime();
5 System.out.print(rt.freeMemory());
6 System.out.println("/" + rt.totalMemory());
7 long start = System.currentTimeMillis();
8 StringBuffer a = new StringBuffer("a");
9 for(int i=0; i < 30000; i++) {
10 a.append("a");
11 }
12 long stop = System.currentTimeMillis();
13 System.out.println(stop - start);
14 System.out.print(rt.freeMemory());
15 System.out.println("/" + rt.totalMemory());
16 }
17
18 }
테스트 결과
String
1830448/2031616
41800 -> 총 소요시간(단위: ms)
967576/2031616
StringBuffer
1830336/2031616
30 -> 총 소요시간(단위: ms)
1673200/2031616
시간 차이도 많이 났지만, 메모리 사용량도 상당한 차이가 있었습니다. 이와 함께 더 큰 문제는 이 작업이 많아질 수로 가비지 콜렉션에 의해 String을 사용하는 경우에 시간에 휠씬 큰 차이로 많이 소요된다는 것입니다.
String클래스와 StringBuffer클래스의 차이점
* String은 문자열의 내용이 조금이라도 바뀌거나 스트링 컨케트네이션되면 새로운
객체를 만든다.
레퍼런스를 잃어버린 객체는 가비지 컬렉션의 대상이 되며 새로운 객체에 새 주소를
주므로 해쉬코드도 변한다. Immutable한 특징도 가지고 있다.
* StringBuffer는 원래 있던 객체의 내용만 바뀌는 Mutable한 특징이 있다.
Mutable : 변덕스러운.
Immutable : 불변의.
StringBuffer 안의 모든 문자열을 지우고 싶을때
StringBuffer sb = new StringBuffer();
sb.append("안녕하세요.abc");
sb.delete(0, sb.length());
무심코 쓰고 있는것들, 하지만 왜~ 쓰냐 ? 를 알아가는것이 중요..!
댓글 4개:
좋은 정보네요.
그런데, 한 가지의 더 팁은 StringBuffer에서 생성할 때 사이즈를 정해주면 좀 더 빨랐던 것으로 기억됩니다. "사이즈를 정하다"에서 얼마만큼의 질문을 하면 좀 애매하긴 한데, 적절한(?) 사이즈를 주면 VM에서는 고민없이(?)(사실 디폴트 값) 그 사이즈를 사용하게 되고, 꽉 차게 되면 그 사이즈만큼 자동으로 늘려주니까. 더 성능이 좋았던 것으로 기억납니다.
따라서, 개발입장에서는 순환문이면 StringBuffer이고 그 외에는 String을 쓰면 될 것 같네요.
아! 그러면, StringBuffer vs. StringBuilder의 차이점도 있겠군요.
안녕하세요. 글에 대한 좋은 평가 감사합니다.
블로그에서 밝힌 대로 글의 내용을 제가 작성한 것은 아닙니다.
하지만 이전에 모아둔 자료를 출저를 밝혀서 올렸던 것입니다.
Richpapa님께서 올리신 내용을 보니 참 좋은 내용이어서 하나 더 덧붙여 봅니다.
실제로 String에 대한 이슈는 튜닝과 관련된 내용입니다.
특히, StringBuffer vs StringBuilder에 대한 내용은 "자바 성능을 결정짓는 코딩 습관과 튜닝 이야기-이상민 지음" Story-04 '왜 자꾸 String을 쓰지 말라는 거야'에서 잘 나와 있습니다.
언급하신 댓글로는 이미 보신 것 같기도 합니다만...^^;;
다른 분들에게 도움이 될까해서 생각해본 대로 적어봤습니다.
다시금 좋은 댓글에 감사합니다^^
@와이즈앤트 - 2009/05/13 10:05
답변 주셔서 고맙습니다. 간혹가다가 SDN 통해서 와서 글을 읽고 가곤 한답니다. ^^
저도 그다지 내공이 깊지는 않지만, 언급하신 책을 봤었는데 그닥 신뢰성이 가지 않았다는 느낌은 비단 저만 드는 것은 아닐 겁니다. 그 책에서 언급한 내용이 "Thinking in Java"에서 말하는 부분이 상당히 많았고, 왜 그런지 설명없이 지나간 부분도 많더라구요. (책 읽는데만 집중이 되서 실력은 낮지만서도)
그래서인지 몰라도(저 같은 사람이 있어서인지는 몰라도) http://kwon37xi.rollinglist.com/list/view.do?listId=27179 여기 가보면 오류 잡는 블로거들도 있더라구요. 참조하시면 도움이 될 것 같습니다.
참, 아들이 2명인가요? (맞지요?) 저도 아들이 둘인데 힘들어 죽겠습니다. ^^
Richpapa님! 좋은 정보 감사합니다^^
오전에 잠시 블로그에 방문드렸는데 도움되는 정보가 많으네요...ㅎㅎ
교류를 자주 맺으면 좋겠습니다. 링크를 걸어둘까요?
참, 저도 아들이 둘입니다. 힘들지만 이 녀석들 때문에 참 즐겁고 소중한 시간이라는 생각이 듭니다^^;;
Richpapa님과는 동병상련도 함께?ㅋ
댓글 쓰기