差StringBuilderおよびStringBuffer
-
21-08-2019 - |
質問
の主な違いは StringBuffer
や StringBuilder
?が性能を決める際はこれらのいずれかの?
解決
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);
}
}
}
A 試運転 の数 2241 ms
のための StringBuffer
vs 753 ms
のための StringBuilder
.
基本的には、 StringBuffer
方法は同期しながら StringBuilder
んでいます。
の操作は"ほぼ"と同じものを同期の方法を単一のスレッドが失わせないアイテムです。
ことになるんです。
見積もりから StringBuilder API:
このクラス[StringBuilder]と互換性があるAPIを提供しますStringBuffer, がいかなる保証も行いませんの同期.このクラスとして用いるために設計されたドのStringBufferの場所での文字列バッファされることとなった単一のスレッド(一般的な例)です。可能な場合に利用することが推奨されているこのプログラミング未経験者を優先的に使用されるStringBufferとして を可能にほとんどの実装方法です。
そのための代替です。
同じっ Vector
や ArrayList
.
しかし、例の助けを借りて、明確な違いを取得するために必要な?
のStringBufferあるいはStringBuilderの
のあなたは本当にスレッド間のバッファを共有しようとしている場合を除き単にStringBuilder
を使用しています。 StringBuilder
は同期していない(少ないオーバーヘッド=より効率的な)元同期StringBuffer
クラスの弟である。の
StringBuffer
が最初に来ました。 Sunは、すべての条件の下で正確と心配していたので、彼らはそれだけの場合には、それはスレッドセーフにするために、同期作られています。
StringBuilder
は後に来ました。 StringBuffer
の用途のほとんどは、シングルスレッドと不必要同期のコストを払っていた。
StringBuilder
はののドロップイン置換 のあるのでStringBuffer
ための同期せずに、任意の実施例間の相違が存在することはないだろう。
は、をした場合は、スレッド間で共有しようとしている、あなたは、例えば、StringBuffer
を使用していますが、より高いレベルの同期が必要であるかどうかを検討することができますおそらく代わりにStringBufferを使用するのではなく、あなたは、StringBuilderのを使用する方法を同期する必要があります。
最初のきの 類似性:両StringBuilderおよびStringBufferは可変です。することができ、内容を変更し、同じ場所です。
の違い:StringBufferは可変と同期しています。にして、StringBuilderが可変で同期化されませんがデフォルトです。
意味の同期(同期):時に一部のものに同期され、その後複数のスレッドにアクセスでき、変更ではの問題や副作用によるものです。StringBufferに同期できますのでご利用いた複数のスレッドは問題です。
を利用できるその他の便利なるのもよいでしょう。 StringBuilder:を必要とする場合、文字列ができ変更可能で、唯一のスレッドがアクセスや変更します。StringBuffer:を必要とする場合、文字列、変更、複数のスレッドがアクセスや変更します。
注意 :なStringBuffer必要以上につないだけのスレッドが正アクセスすので多くのロックおよびロック解除コードの同期を必要以上にCPU時間。使用しないロックない限りが必要です。
単糸 StringBufferなくStringBuilder, は、JVM optimisations.やmultithreadingは使用できなくな安全に、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!
での建より高速バッファは、より高速文字列を連結した.現在利用しましょう、 Executor 複数のスレッド:
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を追加するには遅くとmultithreading利用.その理由は、JIT/ホットスポット/コンパイラ/る事柄についてお話しようと思い最適化合を検出することはありま no 要チェックロックを解除します。
が とStringBuilderには、java.lang.ArrayIndexOutOfBoundsException, で並行スレッドを追加できます。
結論としてのあいだに追StringBuffers.とい糸を考えるように、獲得しようとしているほとが言えます。
それ以前のJVMで動作しません。
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はスレッドセーフではありません。文字列バッファがあります。ここでの詳細情報の のます。
EDIT:パフォーマンスに関しては、中キックのホットスポット後、StringBuilderのが勝者です。しかし、小規模の反復のために、パフォーマンスの違いはごくわずかです。
StringBuilder
とStringBuffer
はほぼ同じです。違いはStringBuffer
が同期され、StringBuilder
ではないということです。 、StringBuilder
がStringBuffer
よりも高速ですが、パフォーマンスの違いはごくわずかです。 StringBuilder
はStringBuffer
の日の代替品です。それだけですべてのパブリックメソッドの同期化を避けることができます。むしろそれよりも、その機能は同じです。
良い使用例:
あなたのテキストを変更しようとしていると複数のスレッドによって使用されている場合、StringBuffer
を使用することをお勧めします。あなたのテキストを変更する予定ですが、単一のスレッドで使用されている場合、StringBuilder
を使用します。
StringBuffer
- 同期がthreadsafe
- スレッドに対して安全が遅い
StringBuilder
- 導入したJava5.0
- 非同期が速く効果的な
- ユーザーのニーズを明示的に同期された場合いたい
- 交換可能ですので
StringBuffer
なしその他の変更
StringBuffer
StringBufferは変更可能な手段で変更の値をオブジェクトです。のオブジェクトの作成を通じてStringBufferに格納されたヒープ.StringBufferと同じ方法として、StringBuilderが、それぞれの方法StringBufferに同期されることはStringBufferはスレッドで安全です。
このことはできませんので二つのスレッドが同時にアクセスしてください。それぞれの方法によりアクセスできるスレッドです。
っているスレッドに対して安全にデメリットものとしての性能の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
String
は不変である。
StringBuffer
は変更可能と同期しています。
StringBuilder
も変更可能であるが、その同期していません。
違いを説明する のJavaDocます:
このクラスは、StringBufferをと互換性のあるAPIを提供しますが、同期の保証なし。 (一般的にそうであるように)このクラスは、文字列バッファが単一のスレッドによって使用された場所でのStringBufferのドロップイン代替品として使用するために設計されています。可能であれば、より速くほとんどの実装の下になるように、このクラスは、StringBufferに、優先して使用することをお勧めします。
StringBuilder
(ジャワ5で導入された)は、StringBuffer
と同一です。これは、後者よりも優れた性能を有することを意味するが、欠点は、スレッドセーフではないということです。
読む<のhref = "https://web.archive.org/web/20130217083932/http://www.leepoint.net/notes-java/data/strings/23stringbufferetc.html" のrel = "noreferrer"詳細について>チュートリアルでます。
の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のは古いのStringBufferのドロップイン代替品です。
StringBuffer
は同期が、StringBuilder
ではありません。その結果、StringBuilder
はStringBuffer
よりも高速です。
StringBuffer は可変です。変更することができさは、長さと内容です。StringBuffersはスレッドセーフで、その同期方法でアクセスの制御を行う唯一のスレッドにアクセスできるStringBufferのオブジェクトの同期化コードです。このように、StringBuffer物は一般的に使用マルチスレッド環境では複数のスレッドがアクセスしようとしているStringBufferと同じオブジェクトでも同時に行います。
StringBuilder の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は、それは複数のスレッドが同時にアクセスしている場合、トラブルがあるかもしれないことを意味し、同期していないことを除いて、StringBufferに、すべての点で同じであるのJava 5で追加されました。シングルスレッドのプログラム、最も一般的なケースでは、同期のオーバーヘッドを回避することは非常にわずかに速いのStringBuilderを行います。
のStringBuilderとStringBufferの間には基本的な違いはありません、唯一のいくつかの違いは、それらの間に存在します。 StringBufferのではメソッドは同期化されています。これは、一度に1つだけのスレッドがそれらを操作できることを意味します。複数のスレッドがある場合は、2番目のスレッドが終了する最初のもののために待機する必要がありますし、3つ目はそうで終了する第一及び第二の1のために待機しなければならないでしょう。これは、プロセスが非常に遅くなり、ひいてはたStringBufferの場合のパフォーマンスが低いです。
一方のStringBuilderのでは非同期されます。これは、一度に複数のスレッドが同時に同じStrinBuilderオブジェクトを操作できることを意味します。これは、StringBuilderのプロセスが非常に速いので、パフォーマンスが高いとなります。
StringBuffer
が同期されるので、、それが故にperforamanceに基づいStringBuilder
よりも、その少し遅い、いくつかの余分な労力を必要とします。
文字列のStringBufferが可変であるように値がここで変更することはできないことを意味不変の目的である。
のStringBufferは、スレッドセーフしたがって同期されるところのStringBuilderが単一スレッドのインスタンスのためではないと好適である。
の主な違いは、StringBuffer
がsyncronizedができますが、複数のスレッドを使用する必要がnot.If StringBuilder
ですされ、その後のStringBufferはrecommended.Butはそのsyncronizedないので、StringBuilder
よりも高速で実行速度StringBuffer
あたりとして、です。
StringBuffer
とStringBuilder
の非同期appendメソッドの同期appendメソッドの内部をチェックします。
<のhref = "http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/StringBuffer.java/?v=source" のrel = "nofollowを"> 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;
}
<のhref = "http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/StringBuilder.java/?v=source" のrel = "nofollowを">の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
を使用し、複数のスレッド間でバッファを共有していないよう。
こちらではの性能試験結果 文字列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");
}
結果:
100000繰り返し処理のための追加テキスト
String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms
10000繰り返し処理のための追加テキスト
String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
- StringBufferレがStringBuilderがないスレッドで安全です。
- StringBuilderによStringBuffer.
- StringBufferに同期されたがStringBuilderがない 同期化されます。
のStringBufferに存在するすべてのメソッドは同期化されます。 したがって、一度に1つのスレッドStringBufferオブジェクトを動作させることができます。 これは、スレッドの待機時間が長くなり、パフォーマンスの問題を作成します。 SUN人々はバージョン1.5でのStringBuilderをintoducedます。
この問題を克服するために