ฉันยุ่งอยู่กับการใช้งานเชิงตรรกะของโครงการในวันธรรมดา ฉันมีเวลาในวันเสาร์ดังนั้นฉันจึงคิดแบบภาษาอังกฤษหนา ๆ ใน Java จากตู้หนังสือและอ่านการประกบของวัตถุสตริง อ้างถึงหนังสือเล่มนี้เป็นการแปลเพิ่มสิ่งที่คุณคิดและเขียนบทความนี้เพื่อบันทึก
วัตถุสตริงที่ไม่เปลี่ยนรูป
ใน Java วัตถุสตริงไม่เปลี่ยนรูป (ไม่เปลี่ยนรูป) ในรหัสคุณสามารถสร้างนามแฝงหลายรายการสำหรับวัตถุสตริง แต่การอ้างอิงของนามแฝงเหล่านี้เหมือนกัน
ตัวอย่างเช่น S1 และ S2 เป็นนามแฝงสำหรับวัตถุ "droidyue.com" และนามแฝงจะถูกเก็บไว้ในการอ้างอิงถึงวัตถุจริง ดังนั้น S1 = S2
String S1 = "Droidyue.com"; String S2 = S1; System.out.println ("S1 และ S2 มีการอ้างอิงเดียวกัน =" + (S1 == S2));ตัวดำเนินการมากเกินไปใน Java
ใน Java ตัวดำเนินการที่โอเวอร์โหลดเท่านั้นเกี่ยวข้องกับการประกบสตริง - นอกจากนั้นนักออกแบบ Java ไม่อนุญาตให้มีผู้ให้บริการรายอื่นมากเกินไป
การวิเคราะห์การประกบกัน
มีค่าใช้จ่ายจริงหรือไม่?
หลังจากทำความเข้าใจสองประเด็นข้างต้นคุณอาจมีความคิดดังกล่าว เนื่องจากวัตถุต่อยนั้นไม่เปลี่ยนรูปแบบการประกบของหลายสาย (สามหรือมากกว่า) จะสร้างวัตถุสตริงกลางที่ไม่จำเป็นอย่างหลีกเลี่ยงไม่ได้
String username = "Andy"; string ate = "24"; string job = "นักพัฒนา"; string info = ชื่อผู้ใช้ + อายุ + งาน;
เพื่อให้ได้ข้อมูลข้างต้นชื่อผู้ใช้และอายุจะถูกประกบเพื่อสร้างวัตถุสตริงชั่วคราว T1 ด้วยเนื้อหาของ Andy24 จากนั้น T1 และงานจะถูกเชื่อมต่อเพื่อสร้างวัตถุข้อมูลที่เราต้องการในตอนท้าย ในหมู่พวกเขามีการสร้าง T1 ระดับกลางและหลังจากสร้าง T1 มันจะไม่ถูกนำกลับมาใช้ใหม่โดยอัตโนมัติซึ่งจะใช้พื้นที่จำนวนหนึ่งอย่างหลีกเลี่ยงไม่ได้ ถ้ามันเป็นประกบกันมาก (สมมติว่ามีหลายร้อยคนพบได้บ่อยในสตริงการโทรไปยังวัตถุ) ค่าใช้จ่ายจะมากขึ้นและประสิทธิภาพจะต่ำกว่ามาก
การประมวลผลการเพิ่มประสิทธิภาพคอมไพเลอร์
มีค่าใช้จ่ายด้านประสิทธิภาพข้างต้นจริงๆหรือไม่? การประกบสตริงเป็นเรื่องธรรมดาไม่มีการเพิ่มประสิทธิภาพการประมวลผลพิเศษหรือไม่? คำตอบคือการปรับให้เหมาะสมนี้จะดำเนินการเมื่อคอมไพเลอร์คอมไพล์. java เป็น bytecode
หากโปรแกรม Java ต้องการเรียกใช้มันจะใช้เวลาสองช่วงเวลาคอมไพล์เวลาและเวลาทำงาน ในเวลาคอมไพล์คอมไพเลอร์ Java (คอมไพเลอร์) แปลงไฟล์ Java เป็น bytecode ที่รันไทม์เครื่องเสมือน Java (JVM) จะเรียกใช้ Bytecode ที่สร้างขึ้น ผ่านช่วงเวลาทั้งสองนี้ Java ได้บรรลุการรวบรวมและวิ่งไปทุกหนทุกแห่ง
มาทดลองกับการปรับให้เหมาะสมในช่วงเวลาการรวบรวมและเราสร้างรหัสชิ้นส่วนที่อาจมีค่าใช้จ่ายด้านประสิทธิภาพ
การต่อชั้นเรียนสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {string username = "Andy"; string age = "24"; string job = "นักพัฒนา"; สตริงข้อมูล = ชื่อผู้ใช้ + อายุ + งาน; System.out.println (ข้อมูล); -Compile Pencatenation.java รับ concatenation.class
Javac concatenation.java
จากนั้นเราใช้ javap เพื่อถอดรหัสไฟล์ concatenation.catenation ที่รวบรวมได้ JAVAP -C concatenation หากไม่พบคำสั่ง Javap โปรดพิจารณาเพิ่มไดเรกทอรีที่ Javap อยู่ในตัวแปรสภาพแวดล้อมหรือใช้เส้นทางเต็มของ Javap
17: 22: 04 -androidyue ~/workspace_adt/strings/src $ javap -c concatenationcompiled จาก "concatenation.java" การต่อชั้นเรียนสาธารณะ {การติดต่อสาธารณะ (); รหัส: 0: aload_0 1: invokespecial #1 // วิธี java/lang/object. "<init>" :() v 4: ส่งคืนโมฆะคงที่สาธารณะหลัก (java.lang.string []); รหัส: 0: LDC #2 // String Andy 2: Store_1 3: LDC #3 // String 24 5: Store_2 6: LDC #4 // String Developer 8: store_3 9: ใหม่ #5 // คลาส java/lang/stringbuilder 12: dup 13: invokespecial #6 // เมธอด Java/lang/lang invokevirtual #7 // เมธอด java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 20: aload_2 21: invokevirtual #7 // วิธี java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 24: aload_3 25: invokevirtual #7 // วิธี java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 28: invokevirtual #8 // เมธอด java/lang/stringbuilder.toString :() ljava/lang/string; 31: ร้านค้า 4 33: getstatic #9 // ฟิลด์ java/lang/system.out: ljava/io/printstream; 36: Aload 4 38: Invokevirtual #10 // วิธี Java/io/printstream.println: (ljava/lang/string;) v 41: return}ในหมู่พวกเขา LDC ร้านค้า ฯลฯ เป็นคำแนะนำ Java bytecode คล้ายกับคำแนะนำการประกอบ ความคิดเห็นต่อไปนี้ใช้เนื้อหาที่เกี่ยวข้องกับ Java สำหรับคำอธิบาย เราจะเห็นได้ว่ามีผู้สร้างสตริงจำนวนมากอยู่ แต่เราเรียกพวกเขาโดยไม่แสดงในรหัส Java นี่คือการเพิ่มประสิทธิภาพที่ทำโดยคอมไพเลอร์ Java เมื่อ Java Compiler พบกับการประกบสตริงมันจะสร้างวัตถุ StringBuilder การประกบที่อยู่เบื้องหลังมันคือการเรียกวิธีการผนวกของวัตถุ StringBuilder ด้วยวิธีนี้จะไม่มีปัญหาที่เรากังวล
การเพิ่มประสิทธิภาพคอมไพเลอร์เพียงอย่างเดียว?
เนื่องจากคอมไพเลอร์ช่วยให้เราเพิ่มประสิทธิภาพได้เพียงพอหรือไม่ที่จะพึ่งพาการเพิ่มประสิทธิภาพของคอมไพเลอร์เพียงอย่างเดียว? ไม่แน่นอน
ลองดูที่โค้ดที่ไม่ได้รับการปรับให้เหมาะสมสำหรับประสิทธิภาพต่ำ
โมฆะสาธารณะ ImplentIsStringBuilder (สตริง [] ค่า) {string result = ""; สำหรับ (int i = 0; i <ค่าความยาว; i ++) {ผลลัพธ์ += ค่า [i]; } system.out.println (ผลลัพธ์);}รวบรวมด้วย javac และดูด้วย javap
11: ใหม่ #5 // คลาส java/lang/stringbuilder 14: dup 15: invokespecial #6 // วิธี java/lang/stringbuilder. "<init>" :() v 18: aload_2 19: invokevirtual #7 // เมธอด 31: store_2 32: iinc 3 java/lang/system.out: ljava/io/printstream; 41: aload_2 42: invokevirtual #10 // วิธี java/io/printstream.println: (ljava/lang/string;) v 45: return
ในหมู่พวกเขา 8: IF_ICMPGE 38 และ 35: GOTO 5 รูปแบบลูป 8: IF_ICMPGE 38 หมายความว่าหากการเปรียบเทียบจำนวนเต็มของ jvm operand stack มากกว่าหรือเท่ากับ (ผลลัพธ์ตรงข้ามของ i <ค่าความยาว) เป็นจริงจากนั้นข้ามไปที่บรรทัด 38 (System.out) 35: Goto 5 หมายถึงการกระโดดโดยตรงไปยังบรรทัด 5
แต่มีสิ่งสำคัญมากที่นี่ที่การสร้างวัตถุ StringBuilder เกิดขึ้นระหว่างลูปซึ่งหมายความว่ากี่ครั้งที่ลูปจะสร้างวัตถุสตริง builder ซึ่งเห็นได้ชัดว่าไม่ดี รหัสระดับต่ำเปลือย
ปรับให้เหมาะสมเล็กน้อยเพื่อปรับปรุงคุณภาพทันที
โมฆะสาธารณะ ExplicitusEstringBuilder (String [] ค่า) {StringBuilder result = new StringBuilder (); สำหรับ (int i = 0; i <value.length; i ++) {result.append (ค่า [i]); -ข้อมูลที่รวบรวมที่สอดคล้องกัน
11: Aload_1 12: ArrayLength 13: IF_ICMPGE 30 16: Aload_2 17: Aload_1 18: Iload_3 19: Aaload 20: Invokevirtual #7 // วิธี Java/Lang/Stringbuilder.Append: (Ljava/Lang/String; 23: ป๊อป 24: IINC 3, 1 27: GOTO 10 30: กลับมา
ดังที่เห็นได้จากด้านบน 13: IF_ICMPGE 30 และ 27: GOTO 10 รูปแบบลูปวนลูปในขณะที่ 0: ใหม่ #5 อยู่นอกลูปดังนั้น StringBuilder จึงไม่ได้สร้างหลายครั้ง
โดยทั่วไปเราต้องพยายามหลีกเลี่ยงการสร้าง StringBuilders โดยนัยหรือโดยนัยในร่างกายลูป ดังนั้นผู้ที่เข้าใจวิธีการรวบรวมรหัสและวิธีการดำเนินการภายในมีระดับรหัสค่อนข้างสูง
หากมีข้อผิดพลาดใด ๆ ในบทความข้างต้นโปรดวิจารณ์และแก้ไขให้ถูกต้อง
ข้างต้นคือการจัดเรียงข้อมูลเกี่ยวกับการประกบสตริง Java และเราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!