문제

무슨의 주요 차이점 StringBufferStringBuilder?은 없는 성능 문제를 결정할 때에 어떤 이들 중 하나?

도움이 되었습니까?

해결책

StringBuffer 동기화되고 StringBuilder 아니다.

다른 팁

StringBuilder 보다 빠릅니다 StringBuffer 그렇지 않기 때문입니다 synchronized.

간단한 벤치 마크 테스트는 다음과 같습니다.

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

테스트 실행 숫자를 제공합니다 2241 ms ~을 위한 StringBuffer vs 753 ms ~을 위한 StringBuilder.

원래, StringBuffer 방법은 동기화됩니다 StringBuilder 그렇지 않습니다.

작업은 "거의"동일하지만 단일 스레드에서 동기화 된 메소드를 사용하는 것은 과잉입니다.

그것은 그것에 관한 것입니다.

인용 StringBuilder API:

이 클래스 [StringBuilder]는 StringBuffer와 호환되는 API를 제공합니다. 그러나 동기화를 보장하지 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer의 드롭 인 교체로 사용하도록 설계되었습니다 (일반적으로 경우와 같이). 가능한 경우이 클래스는 StringBuffer를 선호하는 것이 좋습니다. 대부분의 구현에서는 더 빠릅니다.

그래서 그것을 대체하기 위해 만들어졌습니다.

같은 일이 일어났습니다 Vector 그리고 ArrayList.

그러나 모범의 도움으로 명확한 차이를 얻을 필요가 있습니까?

StringBuffer 또는 StringBuilder

간단히 사용하십시오 StringBuilder 실제로 스레드간에 버퍼를 공유하려고하지 않는 한. StringBuilder 원래 동기화 된 동기화되지 않은 (오버 헤드 = 더 효율적) 남동생입니까? StringBuffer 수업.

StringBuffer 먼저 왔어요. Sun은 모든 조건에서 정확성에 관심이 있었기 때문에 만일을 대비하여 스레드 안전을 만들기 위해 동기화되었습니다.

StringBuilder 나중에왔다. 대부분의 용도 StringBuffer 단일 스레드와 불필요하게 동기화 비용을 지불했습니다.

부터 StringBuilder a 드롭 인 교체 ~을 위한 StringBuffer 동기화가 없으면 예제간에 차이가 없습니다.

만약 너라면 ~이다 스레드를 공유하려고하면 사용할 수 있습니다 StringBuffer, 그러나 StringBuilder를 사용하는 메소드를 동기화 해야하는 StringBuffer를 사용하는 대신 더 높은 수준의 동기화가 필요한지 여부를 고려하십시오.

먼저 보자 유사성: StringBuilder와 StringBuffer는 모두 변이합니다. 즉, 같은 위치에있는 내용을 변경할 수 있습니다.

차이: StringBuffer는 변경 가능하고 동기화되었습니다. AS StringBuilder는 변이 가능하지만 기본적으로 동기화되지는 않습니다.

동기화의 의미 (동기화): 어떤 것이 동기화되면, 여러 스레드가 액세스하고 문제 또는 부작용으로 수정할 수 있습니다. StringBuffer는 동기화되므로 문제가없는 여러 스레드와 함께 사용할 수 있습니다.

언제 사용할 수 있습니까?StringBuilder : 수정 가능할 수있는 문자열이 필요한 경우, 하나의 스레드 만 액세스하고 수정합니다. StringBuffer : 수정 가능하고 여러 스레드가 액세스하고 수정하는 문자열이 필요할 때.

메모 : StringBuffer를 불필요하게 사용하지 마십시오. 즉, 하나의 스레드 만 수정하고 액세스하는 경우 사용하지 마십시오. 필요하지 않은 경우 잠금 장치를 사용하지 마십시오.

에서 하나의 스레드 StringBuffer 하지 않은 크게보다 느리게 StringBuilder, 감사 JVM 최적화되어 있습니다.에서 다중 스레딩을 사용할 수 없습니다 안전하게 StringBuilder.

여기에는 내가 테스트(하지 않는 기준,단 테스트):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

결과:
문자열:319740
버퍼 23
Builder:7!

그래서 건축업자보다 더 빠른 버퍼,그리고 방법보다 빠르게 연결 문자열.지금 사용하자 실행 여러 쓰레드:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

지금 StringBuffers 고 157ms 100000 추가합니다.그것은 동일한 테스트,하지만 이전에 비해 37ms,당신은 안전하다고 가정 StringBuffers 추가는 느리게 다중 스레드를 사용.그 이유는 JIT/핫스팟/컴파일러/무언가를 만드는 최적화를 감지할 때가 있다는 no 에 필요한 검사를 잠급니다.

와 StringBuilder,당신은 java.랭.ArrayIndexOutOfBoundsException, 기 때문에,동시에 실려 무언가를 추가해야 하는 없습니다.

결론은 당신 없이 쫓아 StringBuffers.고 있는 스레드에 대한 생각들이 무엇을 하기 전에 얻으려고 몇 나노초입니다.

StringBuilder는 Java 1.5에서 소개되었으므로 이전 JVMS에서는 작동하지 않습니다.

로부터 Javadocs:

StringBuilder 클래스는 StringBuffer와 호환되는 API를 제공하지만 동기화를 보장하지 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer의 드롭 인 교체로 사용하도록 설계되었습니다 (일반적으로 경우와 같이). 가능한 경우,이 클래스는 대부분의 구현에서 더 빨리 StringBuffer를 선호하는 것이 좋습니다.

꽤 좋은 질문

차이점은 다음과 같습니다.

StringBuffer :-

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder :-

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

일반적인 것 :-

둘 다 동일한 서명으로 동일한 방법을 가지고 있습니다. 둘 다 돌연변이 가능합니다.

StringBuilder는 스레드 안전하지 않습니다. 문자열 버퍼는입니다. 더 많은 정보 여기.

편집 : 성능은 다음과 같습니다 핫스팟 StringBuilder가 승자입니다. 그러나 작은 반복의 경우 성능 차이는 무시할 수 있습니다.

StringBuilder 그리고 StringBuffer 거의 동일합니다. 차이점은 그 것입니다 StringBuffer 동기화되고 StringBuilder 아니다. 하지만, StringBuilder 보다 빠릅니다 StringBuffer, 성능의 차이는 거의 없습니다. StringBuilder 태양의 대체입니다 StringBuffer. 모든 공개 방법의 동기화를 피합니다. 그것보다는 그들의 기능이 동일합니다.

좋은 사용의 예 :

텍스트가 변경되고 여러 스레드가 사용하는 경우 사용하는 것이 좋습니다. StringBuffer. 텍스트가 변경되지만 단일 스레드에서 사용하는 경우 StringBuilder.

StringBuffer

  • 동기화 된 따라서 ThreadSafe
  • 스레드 안전하여 느리게

StringBuilder

  • Java 5.0에서 소개되었습니다
  • 비동기식이므로 빠르고 효율적입니다
  • 사용자가 원하는 경우 명시 적으로 동기화해야합니다.
  • 당신은 그것을 교체 할 수 있습니다 StringBuffer 다른 변화없이

StringBuffer

StringBuffer는 변동성이란 객체의 값을 변경할 수 있음을 의미합니다. StringBuffer를 통해 생성 된 객체는 힙에 저장됩니다. StringBuffer는 StringBuilder와 동일한 메소드를 가지고 있지만 StringBuffer의 각 방법은 stread safe입니다.

이로 인해 두 개의 스레드가 동시에 동일한 방법에 액세스 할 수 없습니다. 각 방법은 한 번에 하나의 스레드로 액세스 할 수 있습니다.

그러나 스레드 안전 속성으로 인해 StringBuffer의 성능이 닿으면 스레드 안전을 유지하면 단점이 있습니다. 따라서 StringBuilder는 각 클래스의 동일한 방법을 호출 할 때 StringBuffer보다 빠릅니다.

StringBuffer 값을 변경할 수 있습니다. 즉, 새 값에 할당 할 수 있습니다. 요즘 가장 일반적인 인터뷰 질문, 위의 수업의 차이점입니다. toString () 메소드를 사용하여 문자열 버퍼를 문자열로 변환 할 수 있습니다.

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder는 StringBuffer와 동일합니다. 즉 객체를 힙에 저장하고 수정할 수도 있습니다. StringBuffer와 StringBuilder의 주요 차이점은 StringBuilder도 스레드 안전하지 않다는 것입니다. StringBuilder는 스레드 안전하지 않기 때문에 빠릅니다.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

enter image description here

자원: String vs StringBuffer vs StringBuilder

String 불변입니다.

StringBuffer 변이 가능하고 동기화됩니다.

StringBuilder 또한 변경 가능하지만 동기화되지는 않습니다.

그만큼 Javadoc 차이점을 설명합니다.

이 클래스는 StringBuffer와 호환되는 API를 제공하지만 동기화를 보장하지 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer의 드롭 인 교체로 사용하도록 설계되었습니다 (일반적으로 경우와 같이). 가능한 경우,이 클래스는 대부분의 구현에서 더 빨리 StringBuffer를 선호하는 것이 좋습니다.

StringBuilder (Java 5에서 소개)는 동일합니다 StringBuffer, 방법을 제외하고는 동기화되지 않습니다. 이것은 후자보다 성능이 향상되었지만 단점은 스레드 안전이 아니라는 것입니다.

읽다 지도 시간 자세한 사항은.

StringBuffer와 StringBuilder의 차이점을 보여주는 간단한 프로그램 :

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

StringBuilder는 동기화되지 않아 성능이 향상되므로 StringBuilder를 더 잘 사용하십시오. StringBuilder는 이전 StringBuffer의 드롭 인 교체입니다.

StringBuffer 동기화되었지만 StringBuilder 아니다. 결과적으로, StringBuilder 보다 빠릅니다 StringBuffer.

StringBuffer 은 변경할 수 있습니다.그것은 변경할 수 있습의 관점에서 길이와 내용입니다.StringBuffers 은 스레드에 안전하는 것을 의미,그들은 동기화 방법에 대한 액세스를 제어하는 단 하나의 스레드에 액세스할 수 있습 StringBuffer 체의 동기화된 코드에서는 시간입니다.따라서,StringBuffer 개체는 일반적으로 안전하에서 사용하는 다중 스레드 환경에서 여러 스레드가 될 수 있습 액세스하려고 하는 같은 StringBuffer 에 있는 객체에 동일한 시간입니다.

StringBuilder 이 클래스는 매우 유사하 StringBuffer 것을 제외하고,그 액세스 동기화되지 않도록 그것은 스레드에 안전합니다.지 않음으로써 동기화되의 성능 StringBuilder 것보다 더 좋을 수 있습 StringBuffer.따라서,에서 작업하는 경우 하나의 스레드 환경을 사용하여,StringBuilder 대신 StringBuffer 에서 발생할 수 있습 향상된 성능을 제공합니다.이러한 다른 상황과 같은 StringBuilder 지역 변수(즉,변수 내에서 방법)는 단 하나의 스레드에 액세스할 StringBuilder 개체입니다.

StringBuffer :

  • 멀티 스레드
  • 동기화
  • StringBuilder보다 느립니다

StringBuilder

  • 싱글 스레드
  • 동기화되지 않았습니다
  • 그 어느 때보 다 더 빨리 문자열

문자열 빌더 :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

문자열 버퍼

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

StringBuffer보다 빠르기 때문에 가능한 경우 StringBuilder를 사용하는 것이 좋습니다. 그러나 스레드 안전이 필요한 경우 가장 좋은 옵션은 StringBuffer 객체입니다.

StringBuffer는 변경 될 문자열을 저장하는 데 사용됩니다 (String 객체를 변경할 수 없습니다). 필요에 따라 자동으로 확장됩니다. 관련 클래스 : 문자열, charSequence.

StringBuilder는 Java 5에 추가되었습니다. StringBuffer와 동일하게 동기화되지 않았다는 점을 제외하고는 모든 스레드가 동시에 액세스하는 경우 문제가 발생할 수 있음을 의미합니다. 단일 스레드 프로그램의 경우 동기화의 오버 헤드를 피하면 가장 일반적인 경우 StringBuilder가 매우 빠르게됩니다.

StringBuilder와 StringBuffer 사이에는 기본적인 차이가 없으며, 그들 사이에는 몇 가지 차이 만 있습니다. StringBuffer에서 방법은 동기화됩니다. 이것은 한 번에 하나의 스레드 만 작동 할 수 있음을 의미합니다. 둘 이상의 스레드가 있으면 두 번째 스레드가 첫 번째 스레드가 끝날 때까지 기다려야하며 세 번째 스레드는 첫 번째와 두 번째 스레드가 끝날 때까지 기다려야합니다. 이로 인해 프로세스가 매우 느려져 StringBuffer의 경우 성능이 낮습니다.

반면에 StringBuilder는 동기화되지 않습니다. 이것은 한 번에 여러 스레드가 동시에 동일한 strinbuilder 객체에서 작동 할 수 있음을 의미합니다. 이로 인해 프로세스가 매우 빠르며 StringBuilder의 성능이 높아집니다.

부터 StringBuffer 동기화되고, 약간의 노력이 필요하므로, 천공을 기반으로하는 것보다 약간 느립니다. StringBuilder.

문자열은 불변의 객체로서 StringBuffer가 변하는 경우 값을 변경할 수 없음을 의미합니다.

StringBuffer는 동기화되므로 StringBuilder가 단일 스레드 인스턴스에만 적합한 경우 스레드 안전합니다.

주요 차이점은입니다 StringBuffer 동기화되었지만 StringBuilder 두 스레드 이상을 사용해야하는 경우 StringBuffer가 권장됩니다. 그러나 실행 속도에 따라 StringBuilder 보다 빠릅니다 StringBuffer , 그것의 동시성이 아니기 때문입니다.

동기화 된 부속 방법의 내부를 확인하십시오 StringBuffer 및 비 동기화 된 첨부 방법 StringBuilder.

StringBuffer:

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder:

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

부록이기 때문에 synchronized, StringBuffer 에 비해 성능 오버 헤드가 있습니다 StrinbBuilder 멀티 스레딩 시나리오에서. 여러 스레드간에 버퍼를 공유하지 않는 한 StringBuilder, 이는 부재로 인해 빠릅니다 synchronized 추가 방법에서.

성능 테스트 결과는 다음과 같습니다 String vs StringBuffer vs StringBuilder. 마지막으로 StringBuilder가 테스트에서 승리했습니다. 테스트 코드 및 결과는 아래를 참조하십시오.

암호:

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

IDEONE에서 나를 실행하십시오

결과:

단일 텍스트를 추가하기위한 100000 반복

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

단일 텍스트를 추가하기위한 100000 반복

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
  • StringBuffer는 스레드 안전하지만 StringBuilder는 스레드 안전하지 않습니다.
  • StringBuilder는 StringBuffer보다 빠릅니다.
  • StringBuffer는 동기화 된 반면 StringBuilder는 동기화되지 않습니다.

StringBuffer에 존재하는 모든 방법은 동기화됩니다. 따라서 한 번에 하나의 스레드 만 StringBuffer 객체를 작동시킬 수 있습니다. 스레드의 대기 시간을 증가 시키고이 문제를 극복하기 위해 성능 문제를 일으 킵니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top