ความแตกต่างหลักระหว่างStringBufferและStringBuilderคืออะไร? มีปัญหาเรื่องประสิทธิภาพเมื่อตัดสินใจเลือกข้อใดข้อหนึ่งเหล่านี้หรือไม่
ความแตกต่างหลักระหว่างStringBufferและStringBuilderคืออะไร? มีปัญหาเรื่องประสิทธิภาพเมื่อตัดสินใจเลือกข้อใดข้อหนึ่งเหล่านี้หรือไม่
คำตอบ:
StringBufferถูกซิงโครไนซ์StringBuilderไม่ใช่
StringBuilderจะเร็วกว่าเพราะมันไม่ได้StringBuffersynchronized
นี่คือการทดสอบมาตรฐานอย่างง่าย:
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สำหรับStringBufferVS สำหรับ753 msStringBuilder
--> 0เป็นวง เอาฉันสักครู่เพื่อรู้ว่ามันหมายถึงอะไร เป็นสิ่งที่ใช้จริงในทางปฏิบัติแทน...; i > 0; i--ไวยากรณ์ปกติหรือไม่
i -->เป็นเรื่องที่น่ารำคาญจริง ๆ ... ฉันคิดว่ามันเป็นลูกศรเพราะความคิดเห็นเกี่ยวกับศิลปะ ASCII
main()นอกจากนี้การวัดประสิทธิภาพของคุณไม่ยุติธรรม ไม่มีการอุ่นเครื่อง
โดยทั่วไปStringBufferวิธีการจะถูกซิงโครไนซ์ในขณะที่StringBuilderไม่ใช่
การดำเนินการ "เกือบ" เหมือนกัน แต่การใช้วิธีการซิงโครไนซ์ในเธรดเดียวนั้นเกินขีด
มันเกี่ยวกับมันมาก
อ้างอิงจากStringBuilder API :
ชั้นนี้ [StringBuilder] มี API เข้ากันได้กับ StringBuffer, แต่มีการรับประกันของการประสานไม่มี คลาสนี้ถูกออกแบบมาเพื่อใช้แทนการแทนที่สำหรับ StringBuffer ในตำแหน่งที่มีการใช้บัฟเฟอร์สตริงโดยเธรดเดี่ยว (โดยทั่วไปจะเป็นกรณี) หากเป็นไปได้ขอแนะนำให้ใช้คลาสนี้ในการกำหนดค่าตามความชอบกับ StringBuffer เนื่องจากจะเร็วกว่าในการนำไปใช้งานส่วนใหญ่
ดังนั้นมันจึงถูกสร้างขึ้นมาเพื่อทดแทนมัน
เช่นเดียวกับที่เกิดขึ้นกับและVectorArrayList
Hashtable HashMap
แต่จำเป็นต้องได้รับความแตกต่างที่ชัดเจนด้วยความช่วยเหลือของตัวอย่างหรือไม่
StringBuffer หรือ StringBuilder
เพียงใช้StringBuilderเว้นแต่คุณพยายามแบ่งบัฟเฟอร์ระหว่างเธรดจริงๆ StringBuilderเป็นหมู่ (= ค่าใช้จ่ายที่มีประสิทธิภาพน้อยกว่า) น้องชายของตรงกันเดิมStringBufferระดับ
StringBufferมาก่อน ดวงอาทิตย์เกี่ยวข้องกับความถูกต้องภายใต้เงื่อนไขทั้งหมดดังนั้นพวกเขาจึงทำการซิงโครไนซ์เพื่อทำให้เธรดปลอดภัยในกรณี
StringBuilderมาในภายหลัง การใช้งานส่วนใหญ่StringBufferเป็นแบบเธรดเดี่ยวและจ่ายค่าใช้จ่ายในการซิงโครไนซ์โดยไม่จำเป็น
ตั้งแต่StringBuilderเป็นดรอปแทนสำหรับStringBufferโดยไม่ตรงกันจะไม่มีความแตกต่างระหว่างตัวอย่างใด ๆ
ถ้าคุณกำลังพยายามที่จะใช้ร่วมกันระหว่างหัวข้อคุณสามารถใช้StringBufferแต่พิจารณาว่าการประสานในระดับสูงเป็นสิ่งที่จำเป็นเช่นอาจจะแทนการใช้ StringBuffer คุณควรประสานวิธีการที่ใช้นั้น StringBuilder
ก่อนอื่นให้ดูความเหมือนกัน : ทั้ง StringBuilder และ StringBuffer นั้นเปลี่ยนแปลงได้ ซึ่งหมายความว่าคุณสามารถเปลี่ยนเนื้อหาของพวกเขาด้วยในตำแหน่งเดียวกัน
ความแตกต่าง : StringBuffer สามารถเปลี่ยนแปลงได้และทำข้อมูลให้ตรงกันเช่นกัน โดยที่เป็น StringBuilder ไม่แน่นอน แต่ไม่ซิงโครไนซ์โดยค่าเริ่มต้น
ความหมายของการซิงโครไนซ์ (การซิงโครไนซ์) : เมื่อบางสิ่งถูกซิงโครไนซ์หลายเธรดสามารถเข้าถึงและแก้ไขโดยไม่เกิดปัญหาหรือผลข้างเคียงใด ๆ StringBuffer ถูกซิงโครไนซ์ดังนั้นคุณสามารถใช้กับหลายเธรดโดยไม่มีปัญหา
จะใช้อันไหนเมื่อไหร่? StringBuilder: เมื่อคุณต้องการสตริงซึ่งสามารถแก้ไขได้และมีเพียงหนึ่งเธรดเท่านั้นที่เข้าถึงและแก้ไข StringBuffer: เมื่อคุณต้องการสตริงซึ่งสามารถแก้ไขได้และหลายกระทู้กำลังเข้าถึงและแก้ไข
หมายเหตุ : อย่าใช้ StringBuffer โดยไม่จำเป็นเช่นไม่ใช้ถ้ามีเพียงหนึ่งเธรดที่กำลังแก้ไขและเข้าถึงเนื่องจากมีการล็อกและปลดล็อกรหัสจำนวนมากสำหรับการซิงโครไนซ์ซึ่งจะใช้เวลา CPU โดยไม่จำเป็น อย่าใช้ล็อคเว้นแต่จะจำเป็น
ในเธรดเดี่ยว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!
ดังนั้นผู้สร้างจึงเร็วกว่าบัฟเฟอร์และวิธีเร็วกว่าการรวมสตริงเข้าด้วยกัน ตอนนี้ลองใช้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 ใช้เวลา157 msต่อการผนวก 100,000 ครั้ง มันไม่ได้เป็นการทดสอบเดียวกัน แต่เมื่อเทียบกับก่อนหน้านี้ 37 มิลลิวินาทีที่คุณได้อย่างปลอดภัยสามารถสมมติว่าStringBuffers ผนวกจะช้ากับ multithreading ใช้ เหตุผลคือ JIT / ฮอตสปอต / คอมไพเลอร์ / บางอย่างทำให้การปรับให้เหมาะสมเมื่อตรวจพบว่าไม่จำเป็นต้องตรวจสอบล็อค
แต่ด้วย StringBuilder คุณมี java.lang.ArrayIndexOutOfBoundsExceptionเนื่องจากเธรดพร้อมกันพยายามเพิ่มบางสิ่งที่ไม่ควร
บทสรุปคือคุณไม่ต้องไล่ล่า StringBuffers และที่ที่คุณมีเธรดให้คิดถึงสิ่งที่พวกเขากำลังทำอยู่ก่อนที่จะลองรับนาโนวินาทีสักสองสาม
withString+="some string"+i+" ; ";ไม่เท่ากับอีกสองลูปดังนั้นจึงไม่ใช่การเปรียบเทียบที่เป็นธรรม
StringBuilder ถูกนำมาใช้ใน Java 1.5 ดังนั้นมันจะไม่ทำงานกับ JVM ก่อนหน้านี้
จากJavadocs :
คลาส StringBuilder จัดเตรียม API ที่เข้ากันได้กับ StringBuffer แต่ไม่รับประกันการซิงโครไนซ์ คลาสนี้ถูกออกแบบมาเพื่อใช้แทนการแทนที่สำหรับ StringBuffer ในตำแหน่งที่มีการใช้บัฟเฟอร์สตริงโดยเธรดเดี่ยว (โดยทั่วไปจะเป็นกรณี) หากเป็นไปได้ขอแนะนำให้ใช้คลาสนี้ในการกำหนดค่าตามความชอบกับ StringBuffer เนื่องจากจะเร็วกว่าในการนำไปใช้งานส่วนใหญ่
StringBuilderไม่ได้
คำถามที่ดีงาม
นี่คือความแตกต่างฉันได้สังเกต:
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.
สิ่งทั่วไป: -
ทั้งสองมีวิธีการเดียวกันที่มีลายเซ็นเหมือนกัน ทั้งสองไม่สามารถเปลี่ยนแปลงได้
StringBuffer
StringBuilder
StringBufferไม่มีการเปลี่ยนแปลงอื่น ๆappendสองครั้งหรือappendและtoStringไม่ปลอดภัย
StringBuilder ไม่ปลอดภัยเธรด String Buffer คือ ข้อมูลเพิ่มเติมที่นี่
แก้ไข: สำหรับประสิทธิภาพหลังจากฮอตสปอตเริ่มเข้า StringBuilder เป็นผู้ชนะ อย่างไรก็ตามสำหรับการทำซ้ำเล็ก ๆ ความแตกต่างด้านประสิทธิภาพนั้นเล็กน้อย
StringBuilderและStringBufferเกือบจะเหมือนกัน ความแตกต่างคือการStringBufferซิงโครไนซ์และStringBuilderไม่ แม้ว่าStringBuilderจะเร็วกว่าStringBufferแต่ความแตกต่างของประสิทธิภาพก็น้อยมาก จะเปลี่ยนของดวงอาทิตย์StringBuilder StringBufferมันหลีกเลี่ยงการซิงโครไนซ์จากวิธีสาธารณะทั้งหมด มากกว่านั้นฟังก์ชั่นของพวกเขาเหมือนกัน
ตัวอย่างการใช้งานที่ดี:
StringBufferถ้าข้อความของคุณจะมีการเปลี่ยนแปลงและถูกใช้โดยหลายกระทู้แล้วมันจะดีกว่าที่จะใช้ ถ้าข้อความของคุณจะมีการเปลี่ยนแปลง StringBuilderแต่จะถูกใช้โดยหัวข้อเดียวแล้วใช้
StringBuffer
StringBuffer ไม่แน่นอนหมายความว่าเราสามารถเปลี่ยนค่าของวัตถุ วัตถุที่สร้างขึ้นผ่าน StringBuffer จะถูกเก็บไว้ในกอง StringBuffer มีวิธีการเดียวกับ StringBuilder แต่แต่ละวิธีใน StringBuffer จะซิงโครไนซ์ที่เป็น StringBuffer มีความปลอดภัยของเธรด
ด้วยเหตุนี้จึงไม่อนุญาตให้สองเธรดเข้าถึงวิธีเดียวกันพร้อมกัน แต่ละวิธีสามารถเข้าถึงได้ครั้งละหนึ่งเธรด
แต่การมีเธรดที่ปลอดภัยก็มีข้อเสียเช่นเดียวกันกับประสิทธิภาพของ StringBuffer ที่นิยมเนื่องจากคุณสมบัติที่ปลอดภัยของเธรด ดังนั้น StringBuilder จะเร็วกว่า StringBuffer เมื่อเรียกวิธีการเดียวกันของแต่ละคลาส
สามารถเปลี่ยนค่า StringBuffer ได้ซึ่งหมายความว่าสามารถกำหนดให้กับค่าใหม่ได้ ทุกวันนี้คำถามสัมภาษณ์ที่พบบ่อยที่สุดคือความแตกต่างระหว่างชั้นเรียนด้านบน String Buffer สามารถแปลงเป็นสตริงได้โดยใช้เมธอด 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 Vs StringBuffer Vs StringBuilder
String เป็นสิ่งที่ไม่เปลี่ยนรูป
StringBuffer คือความไม่แน่นอนและการซิงโครไนซ์
StringBuilder ไม่แน่นอนเช่นกัน แต่ไม่ซิงโครไนซ์
Javadocอธิบายความแตกต่าง:
คลาสนี้ให้ API ที่เข้ากันได้กับ StringBuffer แต่ไม่มีการรับประกันการซิงโครไนซ์ คลาสนี้ถูกออกแบบมาเพื่อใช้แทนการแทนที่สำหรับ 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");
}
}
}
StringBuffer ใช้เพื่อเก็บสตริงอักขระที่จะเปลี่ยนแปลง (ไม่สามารถเปลี่ยนวัตถุสตริง) มันขยายโดยอัตโนมัติตามความจำเป็น คลาสที่เกี่ยวข้อง: String, CharSequence
StringBuilder ถูกเพิ่มเข้าไปใน Java 5 มันเหมือนกันทุกประการกับ StringBuffer ยกเว้นว่ามันจะไม่ถูกซิงโครไนซ์ซึ่งหมายความว่าหากมีหลายเธรดที่เข้าถึงในเวลาเดียวกันอาจมีปัญหาได้ สำหรับโปรแกรมแบบเธรดเดี่ยวกรณีที่พบบ่อยที่สุดการหลีกเลี่ยงค่าใช้จ่ายในการซิงโครไนซ์ทำให้ StringBuilder เร็วขึ้นเล็กน้อย
StringBuilderโดยทั่วไปแล้ววิธีการแบบโลคอลจะเป็นแบบโลคอล
StringBufferถูกซิงโครไนซ์ แต่StringBuilderไม่ใช่ เป็นผลให้จะเร็วกว่าStringBuilderStringBuffer
StringBuffer ไม่แน่นอน มันสามารถเปลี่ยนแปลงในแง่ของความยาวและเนื้อหา StringBuffers เป็น thread-safe ซึ่งหมายความว่าพวกเขามีวิธีการซิงโครไนซ์เพื่อควบคุมการเข้าถึงเพื่อให้มีเพียงหนึ่งเธรดเท่านั้นที่สามารถเข้าถึงรหัสที่ตรงกันของวัตถุ StringBuffer ในเวลาเดียวกัน ดังนั้นวัตถุ StringBuffer โดยทั่วไปจะปลอดภัยที่จะใช้ในสภาพแวดล้อมแบบมัลติเธรดที่หลายเธรดอาจพยายามเข้าถึงวัตถุ StringBuffer เดียวกันในเวลาเดียวกัน
StringBuilder คลาส StringBuilder คล้ายกันมากกับ StringBuffer ยกเว้นว่าการเข้าถึงนั้นไม่ได้ซิงโครไนซ์เพื่อไม่ให้เป็นเธรดที่ปลอดภัย โดยไม่ถูกซิงโครไนซ์ประสิทธิภาพของ StringBuilder สามารถดีกว่า StringBuffer ดังนั้นหากคุณทำงานในสภาพแวดล้อมแบบเธรดเดียวการใช้ StringBuilder แทน StringBuffer อาจส่งผลให้ประสิทธิภาพเพิ่มขึ้น สิ่งนี้ยังเป็นจริงในสถานการณ์อื่น ๆ เช่นตัวแปรโลคัล StringBuilder (เช่นตัวแปรภายในเมธอด) ที่มีเพียงเธรดเดียวเท่านั้นที่เข้าถึงวัตถุ StringBuilder
StringBuffer:
StringBuilder
String c = a + bเทียบเท่ากับString c = new StringBuilder().append(a).append(b).toString()ดังนั้นจึงไม่เร็วขึ้น มันเป็นเพียงที่คุณสร้างขึ้นมาใหม่สำหรับแต่ละสายนัดในขณะที่คุณอาจจะมีเพียงหนึ่ง ( String d = a + b; d = d + c;คือString d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();ในขณะที่StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();จะบันทึกหนึ่ง StringBuilder instanciation)
String-Builder :
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);
ขอแนะนำให้ใช้ StringBuilder ทุกครั้งที่ทำได้เพราะมันเร็วกว่า StringBuffer อย่างไรก็ตามถ้าจำเป็นต้องมีความปลอดภัยของเธรดตัวเลือกที่ดีที่สุดคือวัตถุ StringBuffer
ใช้งานได้ดีขึ้นStringBuilderเนื่องจากไม่มีการซิงโครไนซ์และให้ประสิทธิภาพที่ดีกว่า StringBuilderเป็นดรอปแทนStringBufferของพี่
StringBu(ff|ild)erเป็นตัวแปรท้องถิ่นที่ใช้โดยด้ายเดียวเท่านั้น
เนื่องจากStringBufferมีการซิงโครไนซ์มันต้องใช้ความพยายามพิเศษดังนั้นจึงขึ้นอยู่กับประสิทธิภาพการทำงานของมันซึ่งช้ากว่าStringBuilderเล็กน้อย
ไม่มีความแตกต่างพื้นฐานระหว่างStringBuilderและStringBufferมีเพียงความแตกต่างเล็กน้อยระหว่างพวกเขา ในStringBufferวิธีการทำข้อมูลให้ตรงกัน ซึ่งหมายความว่าในแต่ละครั้งมีเพียงหนึ่งเธรดเท่านั้นที่สามารถทำงานกับเธรดได้ หากมีมากกว่าหนึ่งเธรดเธรดที่สองจะต้องรอเธรดแรกให้เสร็จและเธรดที่สามจะต้องรอเธรดแรกและที่สองให้เสร็จและอื่น ๆ ทำให้กระบวนการช้ามากและด้วยเหตุนี้ประสิทธิภาพในกรณีของStringBufferอยู่ในระดับต่ำ
ในทางตรงกันข้ามStringBuilderจะไม่ทำข้อมูลให้ตรงกัน ซึ่งหมายความว่าในเวลาหลายกระทู้สามารถทำงานบนStringBuilderวัตถุเดียวกันในเวลาเดียวกัน ทำให้กระบวนการรวดเร็วและประสิทธิภาพการทำงานของStringBuilderสูง
A Stringเป็นวัตถุที่ไม่เปลี่ยนรูปซึ่งหมายความว่าค่าไม่สามารถเปลี่ยนแปลงได้ในขณะที่StringBufferไม่แน่นอน
การStringBufferซิงโครไนซ์จึงปลอดภัยเธรดในขณะที่StringBuilderไม่เหมาะสำหรับอินสแตนซ์เธรดเดียวเท่านั้น
ความแตกต่างที่สำคัญStringBufferคือการทำข้อมูลให้ตรงกัน แต่StringBuilderไม่ใช่ถ้าคุณต้องการใช้มากกว่าหนึ่งเธรดแนะนำให้ใช้ StringBuffer แต่ตามความเร็วในการดำเนินการStringBuilderจะเร็วกว่าStringBufferเพราะไม่ได้ทำข้อมูลให้ตรงกัน
ตรวจสอบ internals ของวิธีการผนวกตรงกันของและวิธีการผนวกที่ไม่ตรงกันของStringBufferStringBuilder
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;
}
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");
}
ผลลัพธ์ :
100,000 ซ้ำสำหรับการเพิ่มข้อความเดียว
String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms
10,000 การวนซ้ำสำหรับการเพิ่มข้อความเดียว
String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
StringBuffer ได้รับการซิงโครไนซ์แล้วและมีความปลอดภัยสำหรับเธรด StringBuilder จะไม่ซิงโครไนซ์และเร็วกว่า