"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

오늘이군

문자열 연결 - String, StringBuilder, StringBuffer, +, concat 본문

삶../프로그래밍

문자열 연결 - String, StringBuilder, StringBuffer, +, concat

오늘이군 2018. 8. 14. 17:21
반응형

자바에서 문자열 처리를 할 때 무심코 String name = "홍" + "길동"; 라는 코드를 작성합니다.

예전에 어디선가 StringBuffer 를 사용하라는 얘기를 들었지만
일일이 append 하는 것도 귀찮고
toString() 도 해야 하는 것이 번거롭다는 생각이 들어 더하기 연산을 해버리는 데요,
이게 문제가 있습니다.

String 은 불변(immutable) 객체 입니다.

예를 들면, str = str + "ab"; 은 100번 주소에 객체가 만들어지지만 다시 str 을 변경하려는 시도를 하면
불변 객체 이므로 새롭게 150 번 주소에 생성을 합니다. 그럼 남은 100번은 어떻게 될까요?

네, GC 대상이 됩니다.
무심코 코드를 이렇게 작성하다보면 불필요한 객체가 많이 생겨서 GC 가 빈번히 발생 할 수 있는 것입니다.

표로 알아보겠습니다.

그럼 우리는 문자열 더하기 연산을 할 때에는 StringBuilder 나 StringBuffer 를 써야 합니다.
일반적으로는 StringBuilder 를 사용하면 되고, staitc 으로 선언한 변수이거나 single-ton 메서드 내에 있는 변수에 한하여는 thread 안정성이 보장되는 StringBuffer 를 사용하면 됩니다.

이것이 얼마나 속도 차이가 나는지 코드로 보겠습니다.
아래 내용처럼 50만번 연산을 수행하는데 string 끼리 더하는 연산을 하면 137 초 즉 2분이상이 소요됩니다. 물론 불필요한 객체도 50만-1 건이 생기게 되는 것이고요.
이처럼 좋은 코딩 습관이 중요합니다.


컴파일러의 역할

JDK1.5 버전 이후에는 컴파일 단계에서 String 객체를 사용하더라도 StringBuilder로 컴파일 되도록 변경되었습니다. 그리하여 JDK 1.5 이후 버전에서는 String 클래스를 활용해도 StringBuilder와 성능상으로 차이가 없어졌습니다. 
 String a = b + c + d;
 String a = new StringBuilder(b).append(c).append(d).toString();

하지만 위의 그림 예시처럼 반복 루프를 사용해서 문자열을 더할 때에는 객체를 계속 추가한다는 사실에는 변함이 없습니다.

그렇다면 concat 은 언제 쓰냐?
+ 연산은 null 을 더합니다. 즉, "1" + null 을 하게 되면 결과는 1null 이 나옵니다.
"1".concat(null) 을 하면 NullPointerException 을 발생시켜 의도하지 않은 결과를 방지합니다.


반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
Comments