Вопрос: Разница между StringBuilder и StringBuffer


В чем основное отличие StringBufferа также StringBuilder? Существуют ли какие-либо проблемы с производительностью при принятии решения по любому из них?


1303


источник


Ответы:


StringBufferсинхронизируется, StringBuilderне является.


1436



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против 753 msдля StringBuilder,


660



В основном, StringBufferметоды синхронизируются StringBuilderне.

Операции «почти» одинаковы, но использование синхронных методов в одном потоке является излишним.

Это в значительной степени об этом.

Цитата API-интерфейс StringBuilder :

Этот класс [StringBuilder] предоставляет API, совместимый с StringBuffer, но без гарантии синхронизации , Этот класс предназначен для использования в качестве замены для StringBuffer в местах, где буфера строк используется одним потоком (как это обычно бывает). По возможности рекомендуется, чтобы этот класс использовался вместо StringBuffer как он будет быстрее в большинстве реализаций.

Поэтому было сделано, чтобы заменить его.

То же самое произошло с Vectorа также ArrayList,


225



Но нужно ли получить четкую разницу с помощью примера?

StringBuffer или StringBuilder

Просто используйте StringBuilderесли вы действительно не пытаетесь разделить буфер между потоками. StringBuilderявляется несинхронизированным (менее накладным = более эффективным) младшим братом исходного синхронизированного StringBufferкласс.


149



Сначала давайте посмотрим сходство : Оба StringBuilder и StringBuffer изменяемы. Это означает, что вы можете изменить их содержимое в том же месте.

Различия : StringBuffer изменен и синхронизирован. Если StringBuilder изменен, но не синхронизирован по умолчанию.

Значение синхронизации (синхронизации) : Когда какая-то вещь синхронизирована, несколько потоков могут получить доступ и изменить ее без каких-либо проблем или побочных эффектов. StringBuffer синхронизирован, поэтому вы можете использовать его с несколькими потоками без каких-либо проблем.

Какой из них использовать, когда? StringBuilder: когда вам нужна строка, которая может быть модифицируемой, и только один поток обращается к ней и ее модифицирует. StringBuffer: когда вам нужна строка, которая может быть модифицируемой, и несколько потоков обращаются к ней и изменяют ее.

Заметка : Не используйте StringBuffer без необходимости, т. Е. Не используйте его, если только один поток модифицирует и получает доступ к нему, потому что у него есть много кода блокировки и разблокировки для синхронизации, что излишне потребует процессорного времени. Не используйте блокировки, если это не требуется.


74



В отдельных потоках, 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
Строитель: 7!


Так что строители быстрее, чем буферы, а WAY быстрее, чем конкатенации строк. Теперь давайте использовать душеприказчик для нескольких потоков:

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 берут 157 мс для 100000 добавлений. Это не тот же тест, но по сравнению с предыдущими 37 мс, можно смело предположить, что Добавления StringBuffers медленнее с использованием многопоточности , Причина в том, что JIT / hotspot / компилятор / что-то делает оптимизацию, когда обнаруживает, что есть нет необходимость проверки замков.

Но с StringBuilder, у вас есть java.lang.ArrayIndexOutOfBoundsException , потому что параллельный поток пытается добавить что-то там, где он не должен.

Вывод заключается в том, что вам не нужно преследовать StringBuffers. И где у вас есть темы, подумайте о том, что они делают, прежде чем пытаться получить несколько наносекунд.


42



StringBuilder был представлен в Java 1.5, поэтому он не будет работать с более ранними JVM.

Из Javadocs :

Класс StringBuilder предоставляет API, совместимый с StringBuffer, но без гарантии синхронизации. Этот класс предназначен для использования в качестве замены для StringBuffer в местах, где буфера строк используется одним потоком (как это обычно бывает). По возможности рекомендуется, чтобы этот класс использовался в предпочтении StringBuffer, поскольку в большинстве реализаций он будет быстрее.


37



Pretty Good Question

Here are the differences, i have noticed :

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.

Common thing :-

Both have same methods with same signatures. Both are mutable.


33



StringBuilder is not thread safe. String Buffer is. More info here.

EDIT: As for performance , after hotspot kicks in , StringBuilder is the winner. However , for small iterations , the performance difference is negligible.


19



StringBuilder and StringBuffer are almost the same. The difference is that StringBuffer is synchronized and StringBuilder is not. Although, StringBuilder is faster than StringBuffer, the difference in performance is very little. StringBuilder is a SUN's replacement of StringBuffer. It just avoids synchronization from all the public methods. Rather than that, their functionality is the same.

Example of good usage:

If your text is going to change and is used by multiple threads, then it is better to use StringBuffer. If your text is going to change but is used by a single thread, then use StringBuilder.


19



StringBuffer

StringBuffer is mutable means one can change the value of the object . The object created through StringBuffer is stored in the heap . StringBuffer has the same methods as the StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread safe .

because of this it does not allow two threads to simultaneously access the same method . Each method can be accessed by one thread at a time .

But being thread safe has disadvantages too as the performance of the StringBuffer hits due to thread safe property . Thus StringBuilder is faster than the StringBuffer when calling the same methods of each class.

StringBuffer value can be changed , it means it can be assigned to the new value . Nowadays its a most common interview question ,the differences between the above classes . String Buffer can be converted to the string by using toString() method.

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 is same as the StringBuffer , that is it stores the object in heap and it can also be modified . The main difference between the StringBuffer and StringBuilder is that StringBuilder is also not thread safe. StringBuilder is fast as it is not thread safe .

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

Resource: String Vs StringBuffer Vs StringBuilder


18