본문으로 바로가기

[자바]11. 헷갈리는 String, StringBuffer, StringBuilder

category Language/자바 2021. 7. 30. 14:54
728x90
반응형
SMALL
평소 알고리즘 공부하면서 Scanner 만 썼는데 시간초과가 많이나서 찾아보다가 StringBuilder라는 찾았다.이 빌더를 섞어서 출력하면 더 빠르다는 것이였다. 그리고 관련 정보에서 String, StringBuffer와의 차이점이 무엇인가에 대한 질문이 많았다.
막상 나도 저 차이점에 대해서 제대로 습득하지 못하고 있었다?!?!?!... 깊게좀 공부하자.... 이참에 정리하자 




String

String city = "서울";
String city = "광주";

 

String 의 변수 city는 처음엔 "서울" 이라는 값을 바라보고 있다가

"광주" 라는 값을 다시 바라보게 된다.

그러면 이전의 서울이라는 값은 메모리에 올라간 상태로 이도저도 못하는 쓰레기 값이 된다. 

쓸때없는 메모리 값 이라고 하여이것을 Gabage 라고 하는데 자바에서는 이를 처리해주는 Gabage Collection 기능이 있다

어쨋든 메모리의 낭비가 일어난다. String 같은 경우 새로운 문자열을 생성할때 new 생성자로 만들어 주기 때문에 이런 경우가 발생한다. 결국 동일 객체에서 정보 변경이 불가능하다(불변).

 

 

StringBuilder,StringBuffer

최근 알고리즘 풀다가 알게되어 좋아하는 스트링 빌더....진작 미리 알았더라면..

StringBuilder 는 String 과는 다르게 정보 변경이 가능하다(가변)
정보 변경시 지원되는 delete(), append() 같은 API를 사용하면 되기 때문에 메모리 낭비가 없다.

이제 빌더와 버퍼의 차이가 무엇이냐?

그것을 바로 동기화의 지원유무이다.

StringBuffer 는 synchronized 를 지원하여 멀티쓰레드 환경에서 안전하다.
StringBuilder 는 지원하지 않기때문에 싱글쓰레드 환경에서 주로 쓰인다.

속도도 빌더가 빠르게 때문에 보통 빌더가 자주 쓰인다.

 

뻘짓)진짜로 빌더섞어서 쓰면 빠른지 테스트 해보자(진짜 빌더가 빨랐다..)

0~99출력하기

1)그냥 스캐너만 쓰기

public class Star2447 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);

        int n=Integer.parseInt(sc.next());

        Long start = System.currentTimeMillis();
        for (int i = 0; i <n ; i++) {
            System.out.println("i = " + i);
        }
        Long end = System.currentTimeMillis();
        System.out.println("시간측정: " + (end-start));
    }
}

2)빌더 섞어서 쓰기

public class Star2447 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        StringBuilder sb =new StringBuilder();

        int n=Integer.parseInt(sc.next());

        Long start = System.currentTimeMillis();
        for (int i = 0; i <n ; i++) {
            sb.append(i);
        }
        System.out.println(sb);
        Long end = System.currentTimeMillis();
        System.out.println("시간측정: " + (end-start));
    }
}

 

+테스트 추가

public class BenchTest {
    public static void main(String[] args){
        final String aValue = "abc";

        double startTime1 = System.nanoTime();
        for (int outLoop = 0; outLoop<10; outLoop++){
            String temp1 = makeString(aValue);
        }
        double endTime1 = System.nanoTime();

        double startTime2 = System.nanoTime();
        for (int outLoop = 0; outLoop<10; outLoop++){
            String temp2 = makeStringBuffer(aValue);
        }
        double endTime2 = System.nanoTime();

        double startTime3 = System.nanoTime();
        for (int outLoop = 0; outLoop<10; outLoop++){
            String temp3 = makeStringBuilder(aValue);
        }
        double endTime3 = System.nanoTime();

        double elapsed1 = (endTime1-startTime1)/1000000.0;
        double elapsed2 = (endTime2-startTime2)/1000000.0;
        double elapsed3 = (endTime3-startTime3)/1000000.0;

        System.out.println("String 시간비용: " + elapsed1);
        System.out.println("StringBuffer 시간비용: " + elapsed2);
        System.out.println("StringBuilder 시간비용: " + elapsed3);


    }

    public static String makeString(final String input){
        String a = new String();
        for (int inLoop = 0; inLoop<10000; inLoop++){
            a+=input;
        }
        return a;
    }


    public static String makeStringBuffer(final String input){
        StringBuffer sf = new StringBuffer();
        for (int inLoop = 0; inLoop<10000; inLoop++){
            sf.append(input);
        }
        return sf.toString();
    }


    public static String makeStringBuilder(final String input){
        StringBuilder sb = new StringBuilder();
        for (int inLoop = 0; inLoop<10000; inLoop++){
            sb.append(input);
        }
        return sb.toString();
    }
}

 

 

 

 

728x90
반응형
LIST