StringBuffer กับ String
Java จัดเตรียมStringBuffer
และString
คลาสและString
คลาสนี้ใช้เพื่อจัดการกับสตริงอักขระที่ไม่สามารถเปลี่ยนแปลงได้ ระบุเพียงว่าวัตถุประเภทString
อ่านได้อย่างเดียวและไม่เปลี่ยนรูป StringBuffer
ระดับจะใช้เพื่อแสดงตัวอักษรที่สามารถแก้ไขได้
ความแตกต่างของประสิทธิภาพที่สำคัญระหว่างคลาสทั้งสองนี้StringBuffer
คือเร็วกว่าString
เมื่อทำการเรียงต่อกันอย่างง่าย ในString
โค้ดการจัดการสตริงอักขระจะเชื่อมต่อกันเป็นประจำ การใช้String
คลาสโดยทั่วไปการเรียงต่อกันจะดำเนินการดังนี้:
String str = สตริงใหม่ ("Stanford"); str + = "หาย !!";
หากคุณจะใช้StringBuffer
เพื่อทำการเชื่อมต่อเดียวกันคุณจะต้องมีรหัสที่มีลักษณะดังนี้:
StringBuffer str = StringBuffer ใหม่ ("Stanford"); str.append ("หาย !!");
นักพัฒนามักคิดว่าตัวอย่างแรกข้างต้นมีประสิทธิภาพมากกว่าเพราะพวกเขาคิดว่าตัวอย่างที่สองซึ่งใช้append
วิธีการต่อกันนั้นมีค่าใช้จ่ายสูงกว่าตัวอย่างแรกซึ่งใช้ตัว+
ดำเนินการเพื่อเชื่อมString
วัตถุสองชิ้นเข้าด้วยกัน
ตัว+
ดำเนินการดูเหมือนไร้เดียงสา แต่รหัสที่สร้างขึ้นทำให้เกิดความประหลาดใจ StringBuffer
ในความเป็นจริงการใช้ a for concatenation สามารถสร้างรหัสที่เร็วกว่าการใช้ไฟล์String
. ในการค้นหาว่าทำไมจึงเป็นเช่นนี้เราต้องตรวจสอบ bytecode ที่สร้างขึ้นจากสองตัวอย่างของเรา bytecode สำหรับตัวอย่างที่ใช้String
มีลักษณะดังนี้:
0 new # 7 3 dup 4 ldc # 2 6 invokespecial # 12 9 astore_1 10 new # 8 13 dup 14 aload_1 15 invokestatic # 23 18 invokespecial # 13 21 ldc # 1 23 invokevirtual # 15 26 invokevirtual # 22 29 astore_1
bytecode ที่ตำแหน่ง 0 ถึง 9 ถูกเรียกใช้สำหรับโค้ดบรรทัดแรก ได้แก่ :
String str = สตริงใหม่ ("Stanford");
จากนั้นรหัส bytecode ที่ตำแหน่ง 10 ถึง 29 จะถูกเรียกใช้สำหรับการต่อข้อมูล:
str + = "หาย !!";
สิ่งที่น่าสนใจที่นี่ bytecode ที่สร้างขึ้นสำหรับการเรียงต่อกันจะสร้างStringBuffer
อ็อบเจกต์จากนั้นเรียกใช้append
เมธอดของมันStringBuffer
อ็อบเจกต์ชั่วคราวถูกสร้างขึ้นที่ตำแหน่ง 10 และappend
เมธอดของมันถูกเรียกที่ตำแหน่ง 23 เนื่องจากString
คลาสไม่เปลี่ยนรูปจึงStringBuffer
ต้องใช้สำหรับการต่อข้อมูล
หลังจากดำเนินการต่อกับStringBuffer
วัตถุแล้วจะต้องแปลงกลับเป็นไฟล์String
. ซึ่งทำได้ด้วยการเรียกใช้toString
เมธอดที่ตำแหน่ง 26 เมธอดนี้จะสร้างString
อ็อบเจกต์ใหม่จากStringBuffer
อ็อบเจ็กต์ชั่วคราว การสร้างStringBuffer
วัตถุชั่วคราวนี้และการแปลงกลับเป็นString
วัตถุในภายหลังนั้นมีราคาแพงมาก
โดยสรุปโค้ดสองบรรทัดด้านบนส่งผลให้มีการสร้างวัตถุสามชิ้น:
String
วัตถุที่ตำแหน่ง 0StringBuffer
วัตถุที่ตำแหน่ง 10String
วัตถุที่ตำแหน่ง 26
ตอนนี้เรามาดู bytecode ที่สร้างขึ้นสำหรับตัวอย่างโดยใช้StringBuffer
:
0 new # 8 3 dup 4 ldc # 2 6 invokespecial # 13 9 astore_1 10 aload_1 11 ldc # 1 13 invokevirtual # 15 16 pop
bytecode ที่ตำแหน่ง 0 ถึง 9 ถูกเรียกใช้สำหรับโค้ดบรรทัดแรก:
StringBuffer str = StringBuffer ใหม่ ("Stanford");
จากนั้น bytecode ที่ตำแหน่ง 10 ถึง 16 จะถูกเรียกใช้งานสำหรับการเรียงต่อกัน:
str.append ("หาย !!");
โปรดสังเกตว่าเช่นเดียวกับกรณีในตัวอย่างแรกรหัสนี้เรียกใช้append
วิธีการของStringBuffer
วัตถุ แตกต่างจากตัวอย่างแรกอย่างไรก็ตามไม่จำเป็นต้องสร้างชั่วคราวStringBuffer
แล้วแปลงเป็นString
วัตถุ รหัสนี้สร้างวัตถุเพียงชิ้นเดียวStringBuffer
คือที่ตำแหน่ง 0
สรุปได้ว่าการStringBuffer
เรียงต่อกันเร็วกว่าการString
ต่อข้อมูลอย่างมีนัยสำคัญ เห็นได้ชัดว่าStringBuffer
ควรใช้ s ในการดำเนินการประเภทนี้เมื่อเป็นไปได้ หากต้องการฟังก์ชันการทำงานของString
คลาสให้พิจารณาใช้ a StringBuffer
for concatenation จากนั้นทำการแปลงหนึ่งString
รายการเป็น
เรียนรู้เพิ่มเติมเกี่ยวกับหัวข้อนี้
- " JavaWorldเปิดตัวคอลัมน์ประสิทธิภาพ Java รายสัปดาห์ใหม่" Reggie Hutcherson ( JavaWorld,มีนาคม 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf.html
- "พื้นฐานของประสิทธิภาพ Java" Reggie Hutcherson ( JavaWorld,มีนาคม 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html
- "ปัญหาด้านประสิทธิภาพหรือปัญหาด้านการออกแบบ" Reggie Hutcherson ( JavaWorld,มีนาคม 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html
- "การเพิ่มประสิทธิภาพคอมไพเลอร์" Reggie Hutcherson ( JavaWorld,มีนาคม 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html
เรื่องนี้ "StringBuffer กับ String" เผยแพร่ครั้งแรกโดย JavaWorld