รายละเอียดการเพิ่มประสิทธิภาพรหัส
1. พยายามระบุว่าตัวดัดแปลงสุดท้ายของคลาสและวิธีการ คลาสที่มีตัวดัดแปลงสุดท้ายที่มีตัวดัดแปลงสุดท้ายไม่สามารถได้รับ ใน Java Core API มีตัวอย่างมากมายของการใช้ขั้นสุดท้ายเช่น java.lang.string และทั้งชั้นเรียนถือเป็นที่สิ้นสุด การระบุตัวดัดแปลงสุดท้ายสำหรับคลาสสามารถป้องกันไม่ให้คลาสถูกสืบทอดและการระบุตัวปรับเปลี่ยนสุดท้ายสำหรับวิธีการสามารถป้องกันไม่ให้วิธีการถูกแทนที่ หากมีการระบุคลาสเป็นขั้นสุดท้ายวิธีการทั้งหมดของคลาสนั้นถือเป็นที่สิ้นสุด คอมไพเลอร์ Java จะมองหาโอกาสในการอินไลน์วิธีสุดท้ายทั้งหมด อินไลน์มีความสำคัญอย่างยิ่งในการปรับปรุงประสิทธิภาพการทำงานของ Java
2. พยายามนำการใช้วัตถุกลับมาใช้ซ้ำโดยเฉพาะอย่างยิ่งวัตถุสตริง เมื่อการต่อการต่อสายของสตริงควรใช้ StringBuilder/StringBuffer แทน เนื่องจากเครื่องเสมือน Java ไม่เพียง แต่ต้องใช้เวลาในการสร้างวัตถุพวกเขาอาจต้องใช้เวลาในการรวบรวมและประมวลผลวัตถุเหล่านี้ในอนาคตการสร้างวัตถุจำนวนมากเกินไปจะมีผลกระทบอย่างมากต่อประสิทธิภาพของโปรแกรม
3. ใช้ตัวแปรท้องถิ่นเพื่อเรียกวิธีการให้มากที่สุด พารามิเตอร์ที่ส่งผ่านเมื่อวิธีการโทรและตัวแปรชั่วคราวที่สร้างขึ้นในการโทรจะถูกเก็บไว้บนสแต็กเร็วขึ้น ตัวแปรอื่น ๆ เช่นตัวแปรคงที่ตัวแปรอินสแตนซ์ ฯลฯ ถูกสร้างขึ้นในกองและความเร็วจะช้าลง นอกจากนี้เมื่อตัวแปรที่สร้างขึ้นในสแต็กเสร็จสิ้นเนื้อหาเหล่านี้จะหายไปและไม่จำเป็นต้องมีการรวบรวมขยะเพิ่มเติม
4. ปิดการไหลในเวลา
ในระหว่างการเขียนโปรแกรม Java ให้ระวังเมื่อทำการเชื่อมต่อฐานข้อมูลและการดำเนินการสตรีมมิ่ง I/O หลังการใช้งานให้ปิดทันเวลาเพื่อปล่อยทรัพยากร เนื่องจากการทำงานของวัตถุขนาดใหญ่เหล่านี้จะทำให้เกิดค่าใช้จ่ายของระบบขนาดใหญ่และหากคุณไม่ระวังมันจะนำไปสู่ผลกระทบร้ายแรง
5. พยายามลดการคำนวณตัวแปรซ้ำให้น้อยที่สุดชี้แจงแนวคิด แม้ว่าจะมีเพียงหนึ่งประโยคในวิธีการ แต่ก็ยังคงใช้งานอยู่รวมถึงการสร้างเฟรมสแต็กปกป้องไซต์เมื่อเรียกวิธีการและกู้คืนไซต์เมื่อเรียกวิธีการ ตัวอย่างเช่นการดำเนินการต่อไปนี้:
สำหรับ (inti = 0; i <list.size (); i ++)
{... } แนะนำให้แทนที่ด้วย:
สำหรับ (inti = 0, length = list.size (); i <length; i ++)
-
ด้วยวิธีนี้เมื่อ list.size () มีขนาดใหญ่มากมันจะลดการบริโภคจำนวนมาก
6. พยายามใช้กลยุทธ์การโหลดขี้เกียจนั่นคือสร้างขึ้นเมื่อจำเป็น
7. การใช้ความผิดปกติด้วยความระมัดระวังจะเป็นอันตรายต่อประสิทธิภาพ ในการโยนข้อยกเว้นคุณต้องสร้างวัตถุใหม่ก่อน ตัวสร้างของอินเทอร์เฟซที่สามารถหมุนได้เรียกใช้วิธีการซิงโครไนซ์ในท้องถิ่นที่ชื่อว่า FillinstackTrace () วิธีการ FillinstackTrace () ตรวจสอบสแต็กและรวบรวมข้อมูลการติดตามการโทร ตราบใดที่มีการโยนข้อยกเว้นเครื่องเสมือน Java จะต้องปรับสแต็กการโทรเนื่องจากวัตถุใหม่ถูกสร้างขึ้นระหว่างการประมวลผล ข้อยกเว้นสามารถใช้สำหรับการจัดการข้อผิดพลาดเท่านั้นและไม่ควรใช้เพื่อควบคุมการไหลของโปรแกรม
8. อย่าใช้ลอง ... จับ ... ในลูปควรวางไว้ที่ชั้นนอกสุดสุด
ตามความคิดเห็นที่นำเสนอโดยชาวเน็ตฉันคิดว่านี่เป็นสิ่งที่ควรค่าแก่การพูดคุย
9. หากคุณสามารถประเมินความยาวของเนื้อหาที่จะเพิ่มให้ระบุความยาวเริ่มต้นสำหรับการรวบรวมและคลาสเครื่องมือที่ใช้ในอาร์เรย์เช่น ArrayList, LinkedLlist, StringBuilder, StringBuffer, HashMap, HashSet ฯลฯ
(1) StringBuilder () // ค่าเริ่มต้นเพื่อจัดสรร 16 อักขระ (2) StringBuilder (ขนาด int) // ค่าเริ่มต้นเพื่อจัดสรรอักขระ 16 ตัว (3) StringBuilder (String Str) // ค่าเริ่มต้นเพื่อจัดสรร 16 อักขระ + str.length () ตัวอย่างเช่น StringBuilder ความยาวแสดงจำนวนอักขระที่สตริงปัจจุบันสามารถรักษาได้ เนื่องจากเมื่อ StringBuilder ถึงกำลังการผลิตสูงสุดมันจะเพิ่มความสามารถเป็น 2 ครั้งและเพิ่ม 2 เมื่อใดก็ตามที่ StringBuilder ถึงความจุสูงสุดมันจะต้องสร้างอาร์เรย์อักขระใหม่และคัดลอกเนื้อหาอาร์เรย์ตัวละครเก่าไปยังอาร์เรย์อักขระใหม่ - นี่เป็นการดำเนินการที่ใช้เวลามาก ลองจินตนาการว่าถ้าคุณสามารถประเมินได้ว่า 5,000 อักขระจะถูกเก็บไว้ในอาร์เรย์อักขระโดยไม่ระบุความยาวพลังของ 2 ที่ใกล้เคียงที่สุดถึง 5,000 คือ 4096 และ 2 ที่เพิ่มเข้ามาในการขยายแต่ละครั้งโดยไม่คำนึงถึง 2
(1) ขึ้นอยู่กับ 4096 ใช้สำหรับอาร์เรย์อักขระขนาด 8194 ซึ่งเพิ่มอาร์เรย์ตัวอักษรขนาดใหญ่ถึง 12290 ในครั้งเดียว หากคุณสามารถระบุอาร์เรย์อักขระขนาด 5000 ที่จุดเริ่มต้นมันจะประหยัดพื้นที่มากกว่าสองเท่า (2) คัดลอกอักขระ 4096 ต้นฉบับลงในอาร์เรย์อักขระใหม่ด้วยวิธีนี้ซึ่งไม่เพียง แต่จะเสียพื้นที่หน่วยความจำ แต่ยังลดประสิทธิภาพการทำงานของรหัส ดังนั้นจึงไม่ผิดที่จะตั้งค่าความสามารถในการเริ่มต้นที่สมเหตุสมผลสำหรับการรวบรวมและคลาสเครื่องมือที่ใช้ในอาร์เรย์พื้นฐานซึ่งจะให้ผลลัพธ์ทันที อย่างไรก็ตามโปรดทราบว่าคอลเลกชันเช่น HashMap ที่นำไปใช้ในอาร์เรย์ + รายการที่เชื่อมโยงไม่ควรตั้งขนาดเริ่มต้นเท่ากันกับขนาดโดยประมาณของคุณเนื่องจากความเป็นไปได้ของวัตถุเดียวที่เชื่อมต่อกับตารางเกือบ 0 แนะนำให้ตั้งค่าเริ่มต้นเป็น N 2
10. เมื่อคัดลอกข้อมูลจำนวนมากให้ใช้คำสั่ง system.arraycopy ()
11. การคูณและการแบ่งใช้การดำเนินการกะ
12. อย่าสร้างการอ้างอิงวัตถุอย่างต่อเนื่องในลูป
ตัวอย่างเช่น:
สำหรับ (inti = 1; i <= count; i ++) {object obj = newObject (); -วิธีการนี้จะทำให้การอ้างอิงวัตถุวัตถุนับมีอยู่ในหน่วยความจำ หากการนับมีขนาดใหญ่มันจะใช้หน่วยความจำ ขอแนะนำให้เปลี่ยนเป็น:
Object obj = null; สำหรับ (inti = 0; i <= count; i ++) {obj = newObject ();} ด้วยวิธีนี้มีการอ้างอิงวัตถุวัตถุเดียวในหน่วยความจำ ทุกครั้งที่มีการใช้วัตถุใหม่ () วัตถุอ้างอิงวัตถุจะชี้ไปที่วัตถุที่แตกต่างกัน แต่มีเพียงวัตถุเดียวในหน่วยความจำซึ่งช่วยประหยัดพื้นที่หน่วยความจำได้อย่างมาก
13. ขึ้นอยู่กับการพิจารณาประสิทธิภาพและการตรวจสอบประเภทควรใช้อาร์เรย์ให้มากที่สุด ควรใช้ ArrayList เฉพาะเมื่อไม่สามารถกำหนดขนาดอาร์เรย์ได้
14. พยายามใช้ HashMap, ArrayList และ StringBuilder ไม่แนะนำให้ใช้ Hashtable, Vector และ StringBuffer สามหลังมีค่าใช้จ่ายด้านประสิทธิภาพเนื่องจากการใช้กลไกการซิงโครไนซ์
15. อย่าประกาศอาร์เรย์เป็นแบบคงที่สาธารณะสุดท้าย
เนื่องจากสิ่งนี้ไม่มีความหมายจึงกำหนดเฉพาะการอ้างอิงว่าเป็นแบบคงที่และเนื้อหาของอาร์เรย์ยังสามารถเปลี่ยนแปลงได้ตามต้องการ การประกาศอาร์เรย์เป็นสาธารณะเป็นช่องโหว่ด้านความปลอดภัยซึ่งหมายความว่าอาเรย์สามารถเปลี่ยนแปลงได้โดยชั้นเรียนภายนอก
16. พยายามใช้ซิงเกิลในโอกาสที่เหมาะสม การใช้ Singletons สามารถลดภาระการโหลดลดเวลาในการโหลดและปรับปรุงประสิทธิภาพการโหลด อย่างไรก็ตามไม่ใช่ทุกสถานที่ที่เหมาะสำหรับซิงเกิลตัน พูดง่ายๆคือ Singletons ส่วนใหญ่ใช้กับสามด้านต่อไปนี้:
(1) ควบคุมการใช้ทรัพยากรควบคุมการเข้าถึงทรัพยากรพร้อมกันผ่านการซิงโครไนซ์เธรด (2) ควบคุมการสร้างอินสแตนซ์เพื่อให้บรรลุวัตถุประสงค์ในการประหยัดทรัพยากร (3) ควบคุมการแบ่งปันข้อมูลและเปิดใช้งานการสื่อสารระหว่างกระบวนการหรือเธรดที่ไม่เกี่ยวข้อง
17. พยายามหลีกเลี่ยงการใช้ตัวแปรคงที่ตามต้องการ
คลาสสาธารณะ A {ส่วนตัวคงที่ b B = newB (); - ในเวลานี้วัฏจักรชีวิตของตัวแปรคงที่ B นั้นเหมือนกับคลาส A หากคลาส A ไม่ได้ถูกถอนการติดตั้งวัตถุ B ที่ชี้ไปที่การอ้างอิง B จะอยู่ในหน่วยความจำจนกว่าโปรแกรมจะสิ้นสุดลง
18. ไม่จำเป็นต้องใช้ช่วงเวลาอีกต่อไป เพื่อล้างเซสชันที่ไม่ได้ใช้งานอีกต่อไปเซิร์ฟเวอร์แอปพลิเคชันจำนวนมากมีการหมดเวลาเซสชันเริ่มต้นโดยทั่วไป 30 นาที เมื่อแอปพลิเคชันเซิร์ฟเวอร์ต้องการบันทึกเซสชันมากขึ้นหากมีหน่วยความจำไม่เพียงพอระบบปฏิบัติการจะถ่ายโอนส่วนหนึ่งของข้อมูลไปยังดิสก์ เซิร์ฟเวอร์แอปพลิเคชันอาจทิ้งเซสชันที่ไม่ได้ใช้งานไปยังดิสก์ตามอัลกอริทึม MRU (บ่อยที่สุดที่ใช้บ่อยที่สุด) และอาจส่งข้อยกเว้นหน่วยความจำไม่เพียงพอ หากเซสชั่นจะถูกทิ้งลงในดิสก์จะต้องมีการจัดลำดับก่อน ในกลุ่มขนาดใหญ่วัตถุที่เป็นอนุกรมมีราคาแพง ดังนั้นเมื่อไม่จำเป็นต้องใช้เซสชั่นอีกต่อไปวิธีการ httpsession ของ httpsession จะถูกเรียกในเวลาเพื่อล้างเซสชัน
19. สำหรับคอลเลกชันที่ใช้อินเทอร์เฟซแบบสุ่มเช่น arrayList คุณควรใช้สิ่งที่พบได้บ่อยที่สุดสำหรับลูปแทน foreach loop เพื่อสำรวจสิ่งนี้แนะนำโดย JDK ให้กับผู้ใช้ คำอธิบายของ JDK API เกี่ยวกับอินเทอร์เฟซแบบสุ่มคือ: การใช้อินเทอร์เฟซแบบสุ่มใช้เพื่อระบุว่ารองรับการเข้าถึงแบบสุ่มอย่างรวดเร็ว วัตถุประสงค์หลักของอินเทอร์เฟซนี้คือการอนุญาตให้อัลกอริทึมทั่วไปเปลี่ยนพฤติกรรมของพวกเขาเพื่อให้สามารถให้ประสิทธิภาพที่ดีเมื่อนำไปใช้กับรายการการเข้าถึงแบบสุ่มหรือต่อเนื่อง ประสบการณ์ในทางปฏิบัติแสดงให้เห็นว่าหากอินสแตนซ์ของคลาสที่ใช้อินเทอร์เฟซแบบสุ่มจะเข้าถึงแบบสุ่มประสิทธิภาพของการใช้งานธรรมดาสำหรับลูปจะสูงกว่าการใช้ลูป foreach; ในทางกลับกันหากเข้าถึงตามลำดับมันจะมีประสิทธิภาพมากขึ้นในการใช้ตัววนซ้ำ คุณสามารถใช้รหัสที่คล้ายกับต่อไปนี้เพื่อทำการตัดสิน:
if (รายการ instanceofrandomaccess) {สำหรับ (inti = 0; i <list.size (); i ++) {}} else {iterator <?> iterator = list.iterable (); ในขณะที่ (iterator.hasnext ()) {iterator.next ()}} หลักการดำเนินการพื้นฐานของ foreach loop คือตัววนซ้ำดังนั้นครึ่งหลังของประโยค "ในทางกลับกันถ้ามันเข้าถึงได้ตามลำดับการใช้ตัววนซ้ำจะมีประสิทธิภาพมากขึ้น" หมายความว่าอินสแตนซ์ของคลาสที่เข้าถึงตามลำดับและใช้ foreach loop เพื่อข้าม
20. การใช้บล็อกรหัสที่ซิงโครไนซ์แทนวิธีการซิงโครไนซ์ได้รับการอธิบายอย่างชัดเจนในบทความบล็อกวิธีการล็อคแบบซิงโครไนซ์ในโมดูลมัลติเธรด หากไม่สามารถพิจารณาได้ว่าวิธีการทั้งหมดจะต้องซิงโครไนซ์ให้ลองใช้บล็อกรหัสที่ซิงโครไนซ์เพื่อหลีกเลี่ยงการซิงโครไนซ์รหัสเหล่านั้นที่ไม่จำเป็นต้องซิงโครไนซ์ซึ่งส่งผลต่อประสิทธิภาพการดำเนินการของรหัส
21. ประกาศค่าคงที่เป็นแบบคงที่และตั้งชื่อพวกเขาในเมืองหลวงเพื่อให้เนื้อหาเหล่านี้สามารถใส่ลงในสระคงที่ในระหว่างการรวบรวมหลีกเลี่ยงการคำนวณค่าคงที่ที่สร้างขึ้นในระหว่างการรันไทม์ นอกจากนี้การตั้งชื่อชื่อของค่าคงที่ในทุนยังสามารถอำนวยความสะดวกความแตกต่างระหว่างค่าคงที่และตัวแปร
22. อย่าสร้างวัตถุที่ไม่ได้ใช้อย่านำเข้าชั้นเรียนที่ไม่ได้ใช้
สิ่งนี้ไม่สมเหตุสมผล หาก "ค่าของตัวแปรท้องถิ่นที่ฉันไม่ได้ใช้" และ "การนำเข้า java.util ไม่เคยใช้" ปรากฏในรหัสแล้วโปรดลบเนื้อหาที่ไร้ประโยชน์เหล่านี้
23. หลีกเลี่ยงการใช้การสะท้อนระหว่างการดำเนินการโปรแกรม สำหรับข้อมูลเพิ่มเติมโปรดดูการสะท้อน การสะท้อนกลับเป็นฟังก์ชั่นที่ทรงพลังมากโดย Java ให้กับผู้ใช้ ฟังก์ชั่นที่ทรงพลังมักหมายถึงประสิทธิภาพต่ำ ไม่แนะนำให้ใช้กลไกการสะท้อนในกระบวนการเรียกใช้โปรแกรมโดยเฉพาะอย่างยิ่งวิธีการเรียกใช้วิธีการ หากมีความจำเป็นอย่างแท้จริงวิธีการชี้นำคือการสร้างอินสแตนซ์วัตถุผ่านการสะท้อนและนำไปใช้เป็นหน่วยความจำเมื่อโครงการเริ่มต้น - ผู้ใช้จะสนใจความเร็วในการตอบสนองที่เร็วที่สุดเมื่อมีปฏิสัมพันธ์กับเพื่อนและไม่สนใจว่าจะใช้เวลานานเท่าใด
24. ใช้พูลการเชื่อมต่อฐานข้อมูลและพูลเธรดทั้งพูลใช้เพื่อนำวัตถุกลับมาใช้ใหม่ อดีตสามารถหลีกเลี่ยงการเปิดและปิดการเชื่อมต่อบ่อยครั้งและหลังสามารถหลีกเลี่ยงการสร้างและการทำลายเกลียวบ่อยครั้ง
25. ใช้กระแสอินพุตและเอาต์พุตบัฟเฟอร์สำหรับการดำเนินการ IO
กระแสอินพุตและเอาต์พุตบัฟเฟอร์ ได้แก่ bufferedreader, bufferedWriter, bufferedInputStream, bufferedOutputStream ซึ่งสามารถปรับปรุงประสิทธิภาพของ IO ได้อย่างมาก
26. ใช้ ArrayList สำหรับฉากที่มีการแทรกแบบต่อเนื่องและการเข้าถึงแบบสุ่มมากขึ้นและใช้ LinkedList สำหรับฉากที่มีการลบองค์ประกอบมากขึ้นและการแทรกระดับกลาง
สิ่งนี้เป็นที่รู้จักกันโดยการทำความเข้าใจหลักการของ ArrayList และ LinkedList
27. อย่าปล่อยให้พารามิเตอร์อย่างเป็นทางการมากเกินไปในวิธีการสาธารณะ
วิธีการสาธารณะเป็นวิธีการที่มอบให้กับโลกภายนอก หากคุณให้วิธีการเหล่านี้มากเกินไปพารามิเตอร์อย่างเป็นทางการมีสองข้อเสียหลัก:
1) การละเมิดแนวคิดการเขียนโปรแกรมเชิงวัตถุ Java เน้นว่าทุกอย่างเป็นวัตถุ พารามิเตอร์ที่เป็นทางการมากเกินไปไม่สอดคล้องกับแนวคิดการเขียนโปรแกรมเชิงวัตถุ
2) พารามิเตอร์มากเกินไปจะนำไปสู่การเพิ่มความน่าจะเป็นของข้อผิดพลาดในการเรียกใช้วิธีการ สำหรับจำนวน "มากเกินไป" หมายถึง 3 หรือ 4 ตัวอย่างเช่นเราใช้ JDBC ในการเขียนวิธีการ insertstudentInfo มีข้อมูลนักเรียน 10 สาขาที่จะแทรกลงในตารางนักเรียน พารามิเตอร์ทั้ง 10 นี้สามารถห่อหุ้มในคลาสเอนทิตีเป็นพารามิเตอร์อย่างเป็นทางการของวิธีการแทรก
28. เมื่อเขียนตัวแปรสตริงและค่าคงที่สตริงเท่ากับมันเป็นเคล็ดลับที่ค่อนข้างธรรมดาในการเขียนค่าคงที่สตริงด้านหน้า หากมีรหัสต่อไปนี้:
string str = "123"; ถ้า (str.equals ("123")) {... } ขอแนะนำให้แก้ไขเป็น:
string str = "123"; ถ้า ("123" .equals (str)) {... } สิ่งนี้สามารถหลีกเลี่ยงข้อยกเว้นตัวชี้ว่างเปล่าได้
32. อย่าบังคับให้การแปลงประเภทข้อมูลพื้นฐานต่ำกว่าขอบเขต
33. แปลงชนิดข้อมูลพื้นฐานเป็นสตริง ประเภทข้อมูลพื้นฐาน. toString () เป็นวิธีที่เร็วที่สุดตามด้วย string.valueof (data) และ data + "วิธีที่ช้าที่สุดในการแปลงประเภทข้อมูลพื้นฐานเป็นสามวิธีฉันมีข้อมูลประเภทจำนวนเต็ม i ซึ่งสามารถใช้ i.toString ()
PublicStatic Void Main (String [] args) {intlooptime = 50000; จำนวนเต็ม i = 0; longStartTime = system.currentTimeMillis (); สำหรับ (intj = 0; j <looptime; j ++) {string str = string.valueof (i); } system.out.println ("string.valueof ():" + (System.currentTimeMillis () - เริ่มต้น) + "MS"); startTime = system.currentTimeMillis (); สำหรับ (intj = 0; j <looptime; j ++) {string str = i.toString (); } system.out.println ("integer.toString ():" + (system.currentTimeMillis () - เริ่มต้น) + "MS"); startTime = system.currentTimeMillis (); สำหรับ (intj = 0; j <looptime; j ++) {string str = i+""; } system.out.println ("i + /" /":" + (system.currentTimeMillis () - เริ่มต้น) + "MS");}ผลการทำงานคือ:
string.valueof (): 11msinteger.toString (): 5ms + "": 25ms
ดังนั้นเมื่อคุณแปลงชนิดข้อมูลพื้นฐานเป็นสตริงในอนาคตคุณควรให้ความสำคัญกับการใช้วิธี ToString () เพราะเหตุใดจึงง่ายมาก:
1. เมธอด string.valueof () เรียกว่าเมธอด Integer.toString () ที่ด้านล่าง แต่จะทำการตัดสินสั้น ๆ ก่อนโทร
2. ฉันจะไม่พูดถึงเมธอด Integer.toString () ฉันจะเรียกมันโดยตรง
3. ชั้นล่างของ I + "" ใช้ StringBuilder เพื่อใช้งาน ก่อนอื่นให้ใช้วิธีการต่อท้ายเพื่อแยกมันจากนั้นใช้วิธี TOSTRING () เพื่อรับสตริง เห็นได้ชัดว่ามันเร็วที่สุด 2, เร็วที่สุด 1 และช้าที่สุด 3
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น