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วัตถุในภายหลังนั้นมีราคาแพงมาก

โดยสรุปโค้ดสองบรรทัดด้านบนส่งผลให้มีการสร้างวัตถุสามชิ้น:

  1. Stringวัตถุที่ตำแหน่ง 0
  2. StringBufferวัตถุที่ตำแหน่ง 10
  3. Stringวัตถุที่ตำแหน่ง 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 StringBufferfor concatenation จากนั้นทำการแปลงหนึ่งStringรายการเป็น

Reggie Hutcherson เป็นผู้เผยแพร่ศาสนาของ Sun เขาเผยแพร่เทคโนโลยี Java 2 Platform ของ Sun ทั่วโลกโดยมุ่งเน้นไปที่ J2SE และกลไกการทำงานของ HotSpot

เรียนรู้เพิ่มเติมเกี่ยวกับหัวข้อนี้

  • " 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