StringBuilder vs StringBuffer i Java

1. Oversigt

I denne korte artikel vil vi se på ligheder og forskelle mellem StringBuilder og StringBuffer i Java.

Kort fortalt, StringBuilder blev introduceret i Java 1.5 som erstatning for StringBuffer.

2. Ligheder

Begge StringBuilder og StringBuffer oprette objekter, der indeholder en ændret sekvens af tegn. Lad os se, hvordan dette fungerer, og hvordan det kan sammenlignes med en uforanderlig Snor klasse:

String uforanderlig = "abc"; uforanderlig = uforanderlig + "def";

Selvom det kan se ud som om, ændrer vi det samme objekt ved at tilføje det “Def”, vi skaber en ny, fordi Snor forekomster kan ikke ændres.

Når du bruger en af ​​dem StringBuffer eller StringBuilder, vi kan bruge Tilføj() metode:

StringBuffer sb = ny StringBuffer ("abc"); sb.append ("def");

I dette tilfælde blev der ikke oprettet noget nyt objekt. Vi har kaldt Tilføj() metode til sb forekomst og ændret dets indhold. StringBuffer og StringBuilder er foranderlige genstande.

3. Forskelle

StringBuffer er synkroniseret og derfor trådsikker.StringBuilder er kompatibel med StringBuffer API men uden garanti for synkronisering.

Da det ikke er en trådsikker implementering, er det hurtigere, og det anbefales at bruge det på steder, hvor der ikke er behov for trådsikkerhed.

3.1. Ydeevne

I små iterationer er præstationsforskellen ubetydelig. Lad os lave et hurtigt mikro-benchmark med JMH:

@State (Scope.Benchmark) offentlig statisk klasse MyState {int iterationer = 1000; Streng initial = "abc"; String suffix = "def"; } @Benchmark public StringBuffer benchmarkStringBuffer (MyState state) {StringBuffer stringBuffer = new StringBuffer (state.initial); for (int i = 0; i <state.iterations; i ++) {stringBuffer.append (state.suffix); } returnere stringBuffer; } @Benchmark public StringBuilder benchmarkStringBuilder (MyState state) {StringBuilder stringBuilder = new StringBuilder (state.initial); for (int i = 0; i <state.iterations; i ++) {stringBuilder.append (state.suffix); } returner stringBuilder; }

Vi har brugt standard Gennemstrømning mode - dvs. operationer pr. tidsenhed (højere score er bedre), hvilket giver:

Benchmark Mode Cnt Score Fejlenheder StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops / s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops / s

Hvis vi øger antallet af iterationer fra 1k til 1m, får vi:

Benchmark Mode Cnt Score Error Units StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops / s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops / s

Lad os dog huske på, at dette er et mikro-benchmark, som måske eller måske ikke har en reel indflydelse på den faktiske virkelighed i en applikation.

4 konklusioner

Kort sagt, den StringBuffer er en trådsikker implementering og derfor langsommere end StringBuilder.

I programmer med en tråd kan vi tage af StringBuilder. Endnu, præstationsgevinsten på StringBuilder over StringBuffer kan være for lille til at retfærdiggøre udskiftning af det overalt. Det er altid en god ide at profilere applikationen og forstå dens køreegenskaber inden for runtime-ydelse, inden du udfører nogen form for arbejde for at erstatte en implementering med en anden.

Endelig, som altid, kan koden, der blev brugt under diskussionen, findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found