String.concat, +, StringBuilder.append 동작 방식 비교

겔로그·2024년 8월 23일
0

오늘은 예전에 받았던 면접 질문 중 하나였던 '+ 연산자는 어떻게 동작하는지?'를 넘어 문자열이 어떻게 처리되는지 확인해보는 시간을 가져보겠습니다.

String.concat

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
 }

String concat 메소드를 볼 경우 메모리 할당이 각기 다르게 되는 것을 알 수 있습니다.

  • value : 추가되는 문자열
  • str: 추가할 문자열
  • new String(buf, true)

기존 문자열의 길이와 추가할 문자열의 길이를 합산하여 해당 크기만큼의 배열을 할당합니다. 할당한 배열에 기존 문자열과 추가할 문자열을 문자로 할당하는 작업을 거친 뒤 String 객체를 만들어 반환합니다.

+

'+' 연산자는 정의하는 방법에 따라 컴파일이 다르게 됩니다.

1. 개행하지 않을 경우

작성된 코드

String str = "1" + "2" + "3"; 

컴파일된 코드

String str = "123";

2. 개행한 경우

작성된 코드

String str2 = "";
    str2 += 0;
    str2 += 1;
    str2 += 2;

컴파일된 코드

String str2 = "";
    str2 = (new StringBuilder()).append(s1).append("0").toString();
    str2 = (new StringBuilder()).append(s1).append("1").toString();
    str2 = (new StringBuilder()).append(s1).append("2").toString();

개행이 되지 않은 경우, 간단한 문자열에 대해선 자체적으로 통합하는 것을 확인할 수 있습니다. 개행이 될 경우 StringBuilder를 활용하여 컴파일된다는 것을 알 수 있습니다.

3. StringBuilder.append

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}
    
private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

ensureCapacityInternal 메소드에서 추가할 문자열인 str 만큼만 배열을 추가할당하여 문자열을 추가하는 것을 확인하실 수 있습니다.

결론

  • String.concat은 사용시 사용대상 문자열 크기 * 2 만큼의 메모리를 할당하여 사용합니다.
  • '+' 연산자는 상황에 따라 컴파일이 다르게 됩니다. 문자열로 합칠수도 있고, StringBuilder로 변환될 수 있습니다.
  • StringBuilder는 필요한 크기만큼만 메모리를 할당하여 사용합니다.

3개를 모두 확인했을땐 초기 생성비용을 제외하면 StringBuilder.append를 사용하는 것이 제일 바람직해 보입니다.

감사합니다.

profile
Gelog 나쁜 것만 드려요~

0개의 댓글