String、StringBuffer、StringBuilderの違いとパフォーマンスの違いを分析します.
2405 ワード
前奏:3つの違いを比較するのは、彼らが同じことをしていることを区別するときの違いです.それは、私たちがよく見ているピンイン文字列のとき、StringBuffer、StringBuilderが呼び出したのはappende()メソッドで、Stringは特別で、「+」号の方程式を採用しています.
説明:はっきりしたいなら、ソースコードを見て、はっきり書いて、自分で何回かテストすることをお勧めします.
まずテスト結果を見てください.
テスト回数
String(ミリ秒)
StringBuffer(ミリ秒)
StringBuilder(ミリ秒)
1万回
69
1
1
10万回
5822
2
1
20万回
22165
5
3
30万回
53970
8
5
50万回
186168
12
10
結論:String>StringBuffer>StringBuilder(結果は自分のこのパソコンだけに対して、一定の参考意義しかなく、完全に正しいとは保証されていません)
結果はJDKのデザインコンセプトと一致しています.もちろん、もともとこのような結果になるはずです.
事実上:1.StringBufferとStringBuilderの違いはスレッドセキュリティのみで、JDKソースコードにはStringBufferのappendにsynchronizedキーワードが表示されていますが、StringBuilderにはないので、StringBufferの性能はStringBuilderより弱いに違いありません.
2.StringとStringBufferの違いは、Stringが文字列の結合を行う際にnew StringBuilder操作が大量に行われていることであり、これはJVMにとってオブジェクトの作成にかかるオーバーヘッドが実は大きく、ここでは性能の弱点1である.String内部は依然としてStringBuilderを採用して実現され、Stringオブジェクトはfinalであるため、前の多くのnew操作を加えると、多くのゴミが発生し、ゴミ回収のオーバーヘッドが増加し、これは性能の弱点である.実際には文字列操作は最終的にシステムのローカルコピー配列の操作を呼び出すが、ローカルメソッドを呼び出す前にStringのオーバーヘッドが大きく、主にStringがどの操作をする配列も固定されており、配列をコピーすることで接合問題を解決するしかなく、性能は比較的弱いが、StringBufferとStringBuilderには拡張メカニズムがあり、つまりソースコードの中の拡張方法があり、以下のコードを参照してください.
ここでさらにJDKの拡張について補足すると、StringBufferと集合フレームワークの拡張はよく設計されており、新規の長さがデフォルトの拡張容量を大きく超えると、新規の長さをベース長とし、その後の拡張もこのベース容量に基づいて拡張される.そうでなければ、一度に1万個の要素を加えると、何度も拡張され、パフォーマンスに与える影響はかなり大きいです.
参考までに、何か間違いがあったら、兄弟たちが提出して、みんなで研究して、一緒に進歩することを歓迎します.
説明:はっきりしたいなら、ソースコードを見て、はっきり書いて、自分で何回かテストすることをお勧めします.
まずテスト結果を見てください.
テスト回数
String(ミリ秒)
StringBuffer(ミリ秒)
StringBuilder(ミリ秒)
1万回
69
1
1
10万回
5822
2
1
20万回
22165
5
3
30万回
53970
8
5
50万回
186168
12
10
結論:String>StringBuffer>StringBuilder(結果は自分のこのパソコンだけに対して、一定の参考意義しかなく、完全に正しいとは保証されていません)
結果はJDKのデザインコンセプトと一致しています.もちろん、もともとこのような結果になるはずです.
事実上:1.StringBufferとStringBuilderの違いはスレッドセキュリティのみで、JDKソースコードにはStringBufferのappendにsynchronizedキーワードが表示されていますが、StringBuilderにはないので、StringBufferの性能はStringBuilderより弱いに違いありません.
2.StringとStringBufferの違いは、Stringが文字列の結合を行う際にnew StringBuilder操作が大量に行われていることであり、これはJVMにとってオブジェクトの作成にかかるオーバーヘッドが実は大きく、ここでは性能の弱点1である.String内部は依然としてStringBuilderを採用して実現され、Stringオブジェクトはfinalであるため、前の多くのnew操作を加えると、多くのゴミが発生し、ゴミ回収のオーバーヘッドが増加し、これは性能の弱点である.実際には文字列操作は最終的にシステムのローカルコピー配列の操作を呼び出すが、ローカルメソッドを呼び出す前にStringのオーバーヘッドが大きく、主にStringがどの操作をする配列も固定されており、配列をコピーすることで接合問題を解決するしかなく、性能は比較的弱いが、StringBufferとStringBuilderには拡張メカニズムがあり、つまりソースコードの中の拡張方法があり、以下のコードを参照してください.
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
ここでさらにJDKの拡張について補足すると、StringBufferと集合フレームワークの拡張はよく設計されており、新規の長さがデフォルトの拡張容量を大きく超えると、新規の長さをベース長とし、その後の拡張もこのベース容量に基づいて拡張される.そうでなければ、一度に1万個の要素を加えると、何度も拡張され、パフォーマンスに与える影響はかなり大きいです.
参考までに、何か間違いがあったら、兄弟たちが提出して、みんなで研究して、一緒に進歩することを歓迎します.