นักพัฒนาส่วนใหญ่เชื่อว่าการเพิ่มประสิทธิภาพประสิทธิภาพเป็นปัญหาที่ค่อนข้างซับซ้อนและต้องใช้ประสบการณ์และความรู้มากมาย ใช่ไม่มีอะไรผิดปกติกับสิ่งนั้น เป็นที่ยอมรับการเพิ่มประสิทธิภาพแอปพลิเคชันของคุณเพื่อประสิทธิภาพที่ดีที่สุดไม่ใช่เรื่องง่าย แต่นั่นไม่ได้หมายความว่าคุณไม่สามารถทำอะไรได้โดยไม่ได้รับประสบการณ์และความรู้นี้ นี่คือเคล็ดลับที่ง่ายต่อการติดตามและแนวทางปฏิบัติที่ดีที่สุดที่สามารถช่วยให้คุณสร้างแอปพลิเคชันที่มีประสิทธิภาพได้ดี
คำแนะนำเหล่านี้ส่วนใหญ่เป็นแบบจาวา แต่ไม่จำเป็นต้องใช้และบางอย่างสามารถนำไปใช้กับแอปพลิเคชันทั้งหมดและภาษาการเขียนโปรแกรม ก่อนที่เราจะแบ่งปันเคล็ดลับการปรับแต่งประสิทธิภาพที่ใช้ Java ให้พูดคุยเกี่ยวกับเคล็ดลับการปรับแต่งประสิทธิภาพทั่วไปเหล่านี้
1. อย่าปรับให้เหมาะสมก่อนจำเป็น
นี่อาจเป็นหนึ่งในเคล็ดลับการปรับแต่งประสิทธิภาพที่สำคัญที่สุด คุณควรปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดทั่วไปและพยายามใช้กรณีการใช้งานของคุณอย่างมีประสิทธิภาพ แต่นั่นไม่ได้หมายถึงการเปลี่ยนไลบรารีมาตรฐานหรือการสร้างการเพิ่มประสิทธิภาพที่ซับซ้อนก่อนที่จะพิสูจน์ว่าจำเป็น
ในกรณีส่วนใหญ่การเพิ่มประสิทธิภาพก่อนวัยอันควรใช้เวลามากทำให้รหัสอ่านและบำรุงรักษายาก ยิ่งไปกว่านั้นการเพิ่มประสิทธิภาพเหล่านี้มักจะไม่นำประโยชน์ใด ๆ เพราะคุณใช้เวลาส่วนใหญ่ในการปรับส่วนที่ไม่สำคัญของแอปพลิเคชันของคุณ
ดังนั้นคุณจะพิสูจน์ได้อย่างไรว่าคุณต้องการเพิ่มประสิทธิภาพบางอย่าง?
ก่อนอื่นคุณต้องกำหนดความเร็วของรหัสแอปพลิเคชันของคุณเช่นระบุเวลาตอบสนองสูงสุดสำหรับการโทร API ทั้งหมดหรือระบุจำนวนระเบียนที่จะนำเข้าในช่วงเวลาที่กำหนด เมื่อเสร็จแล้วคุณสามารถวัดได้ว่าส่วนใดของแอปพลิเคชันจะช้าเกินไปที่จะปรับปรุง หลังจากทำสิ่งนี้แล้วให้ดูเคล็ดลับการปรับจูนที่สองต่อไป
2. ใช้เครื่องวิเคราะห์เพื่อค้นหาคอขวดจริง
หลังจากที่คุณทำตามคำแนะนำชิ้นแรกและพิจารณาว่าบางส่วนของแอปพลิเคชันของคุณต้องการการปรับปรุงให้ถามตัวเองว่าจะเริ่มต้นตรงไหน?
คุณสามารถแก้ปัญหานี้ได้สองวิธี:
สำหรับสาเหตุที่วิธีที่สองควรปฏิบัติตามเสมอ
คำตอบควรชัดเจนและวิธีการที่ใช้เครื่องวิเคราะห์จะช่วยให้คุณเข้าใจประสิทธิภาพของรหัสของคุณได้ดีขึ้นและช่วยให้คุณมุ่งเน้นไปที่ส่วนที่สำคัญที่สุด หากคุณเคยใช้ตัวแยกวิเคราะห์คุณจะประหลาดใจที่ส่วนของรหัสทำให้เกิดปัญหาประสิทธิภาพ อย่างไรก็ตามหลายครั้งการเดาครั้งแรกของคุณจะนำคุณไปในทิศทางที่ผิด
3. สร้างชุดทดสอบประสิทธิภาพสำหรับแอปพลิเคชันทั้งหมด
นี่เป็นเคล็ดลับทั่วไปอีกประการหนึ่งที่จะช่วยให้คุณหลีกเลี่ยงปัญหาที่ไม่คาดคิดมากมายที่เกิดขึ้นหลังจากการปรับปรุงประสิทธิภาพจะถูกนำไปใช้กับสภาพแวดล้อมการผลิต คุณควรกำหนดชุดทดสอบประสิทธิภาพที่ทดสอบแอปพลิเคชันทั้งหมดและเรียกใช้ก่อนและหลังการปรับปรุงประสิทธิภาพให้เสร็จสมบูรณ์
การทดสอบเพิ่มเติมเหล่านี้จะช่วยให้คุณระบุผลกระทบการทำงานและประสิทธิภาพของการเปลี่ยนแปลงและตรวจสอบให้แน่ใจว่าคุณไม่ปล่อยการอัปเดตที่ทำอันตรายมากกว่าดี สิ่งนี้มีความสำคัญอย่างยิ่งหากงานของคุณทำงานในหลายส่วนของแอปพลิเคชันเช่นฐานข้อมูลหรือแคช
4. ก่อนอื่นแก้ปัญหาคอขวดที่ใหญ่ที่สุด
หลังจากสร้างชุดทดสอบและใช้เครื่องวิเคราะห์เพื่อวิเคราะห์แอปพลิเคชันคุณมีรายการคำถามที่ต้องปรับปรุงประสิทธิภาพซึ่งยอดเยี่ยม แต่ก็ยังไม่ตอบคำถามที่คุณควรเริ่มต้น คุณสามารถเริ่มต้นด้วยสิ่งที่สามารถทำได้อย่างรวดเร็วหรือเริ่มต้นด้วยคำถามที่สำคัญที่สุด
แน่นอนว่าอดีตเป็นสิ่งล่อใจมากเพราะมันจะให้ผลลัพธ์ในไม่ช้า บางครั้งอาจจำเป็นต้องโน้มน้าวให้สมาชิกในทีมคนอื่น ๆ หรือผู้บริหารของคุณว่าการวิเคราะห์ประสิทธิภาพนั้นคุ้มค่า
แต่โดยรวมแล้วฉันขอแนะนำให้เริ่มต้นด้วยปัญหาประสิทธิภาพที่สำคัญที่สุดก่อน สิ่งนี้จะทำให้คุณมีการปรับปรุงประสิทธิภาพที่ยิ่งใหญ่ที่สุดและคุณอาจต้องแก้ไขปัญหาเหล่านี้เพียงเล็กน้อยเพื่อแก้ปัญหาความต้องการด้านประสิทธิภาพของคุณ
หลังจากทำความเข้าใจเทคนิคการปรับแต่งประสิทธิภาพทั่วไปลองมาดูเทคนิคการปรับแต่งเฉพาะของ Java
5. ใช้ StringBuilder เพื่อเชื่อมต่อสตริงแบบโปรแกรม
มีตัวเลือกที่แตกต่างกันมากมายสำหรับการเชื่อมต่อสตริงใน Java ตัวอย่างเช่นคุณสามารถใช้ simple + หรือ + =, stringbuffer เก่าหรือ stringbuilder
ดังนั้นคุณควรเลือกวิธีใด
คำตอบขึ้นอยู่กับรหัสที่เชื่อมต่อสตริง หากคุณเพิ่มเนื้อหาใหม่ลงในสตริงตัวอย่างเช่นในการวนรอบคุณควรใช้ StringBuilder ใช้งานง่ายกว่าและให้ประสิทธิภาพที่ดีกว่า StringBuffer แต่โปรดจำไว้ว่า StringBuilder นั้นแตกต่างจาก StringBuffer มันไม่ปลอดภัยกับเธรดและอาจไม่เหมาะสำหรับกรณีการใช้งานทั้งหมด
คุณเพียงแค่ต้องยกตัวอย่างสตริงใหม่และเรียกใช้วิธีการผนวกเพื่อเพิ่มส่วนใหม่ลงในสตริง หลังจากที่คุณเพิ่มชิ้นส่วนทั้งหมดแล้วคุณสามารถเรียกวิธี ToString () เพื่อดึงสตริงการเชื่อมต่อ
ตัวอย่างโค้ดต่อไปนี้แสดงตัวอย่างง่ายๆ ในระหว่างการวนซ้ำแต่ละครั้งลูปนี้จะแปลง I เป็นสตริงและเพิ่มลงในพื้นที่ของ StringBuilder SB ดังนั้นในตอนท้ายรหัสนี้เขียนถึง "นี่คือ test0123456789" ไปยังไฟล์บันทึก
StringBuilder sb = new StringBuilder ("นี่คือการทดสอบ"); สำหรับ (int i = 0; i <10; i ++) {sb.append (i); sb.append ("");} log.info (sb.toString ());อย่างที่คุณเห็นในตัวอย่างโค้ดคุณสามารถให้องค์ประกอบแรกของสตริงสำหรับวิธีการสร้าง สิ่งนี้จะสร้าง StringBuilder ใหม่ด้วยสตริงที่ให้ไว้และความจุอักขระเพิ่มเติม 16 ตัว เมื่อคุณเพิ่มอักขระเพิ่มเติมลงใน StringBuilder JVM จะเปลี่ยนขนาดของ StringBuilder แบบไดนามิกแบบไดนามิก
หากคุณรู้อยู่แล้วว่าสตริงของคุณมีอักขระกี่ตัวคุณสามารถระบุหมายเลขนี้ให้กับวิธีการสร้างที่แตกต่างกันเพื่อสร้างอินสแตนซ์ Stringbuilder ด้วยความจุที่กำหนดไว้ สิ่งนี้จะช่วยเพิ่มประสิทธิภาพเพิ่มเติมเนื่องจากไม่จำเป็นต้องขยายกำลังการผลิตแบบไดนามิก
6. ใช้ +สตริงการเชื่อมต่อในการประกาศ
เมื่อคุณใช้แอปพลิเคชันแรกของคุณใน Java ใครบางคนอาจบอกคุณว่าคุณไม่ควรใช้ + เพื่อเชื่อมโยงสตริง สิ่งนี้ถูกต้องหากคุณเชื่อมต่อสตริงในตรรกะแอปพลิเคชัน สตริงนั้นไม่เปลี่ยนรูปและผลลัพธ์ของการต่อกันของแต่ละสตริงจะถูกเก็บไว้ในวัตถุสตริงใหม่ สิ่งนี้ต้องใช้หน่วยความจำเพิ่มเติมและทำให้แอปพลิเคชันช้าลงโดยเฉพาะอย่างยิ่งเมื่อเชื่อมต่อหลายสตริงในลูป
ในกรณีเหล่านี้คุณควรทำตามเคล็ดลับ 5 และใช้ StringBuilder
แต่ถ้าคุณเพิ่งแบ่งสตริงเป็นหลายบรรทัดเพื่อปรับปรุงความสามารถในการอ่านรหัสของคุณนั่นไม่ใช่กรณี
แบบสอบถาม Q = em.Createquery ("เลือก A.ID, A.FirstName, A.lastName"+ "จากผู้แต่ง A"+ "โดยที่ A.ID =: ID");ในกรณีเหล่านี้คุณควรใช้ Simple + เพื่อเชื่อมต่อสตริงของคุณ คอมไพเลอร์ Java จะปรับให้เหมาะสมและทำการเชื่อมต่อในเวลาคอมไพล์ ดังนั้นเมื่อรันไทม์รหัสใช้เพียง 1 อักขระและไม่จำเป็นต้องมีการต่อกัน
7. ใช้ประเภทข้อมูลพื้นฐานให้มากที่สุด
อีกวิธีที่รวดเร็วในการหลีกเลี่ยงค่าใช้จ่ายและเพื่อปรับปรุงประสิทธิภาพของแอปพลิเคชันคือการใช้ชนิดข้อมูลดั้งเดิมแทนคลาส wrapper ดังนั้นจึงเป็นการดีกว่าที่จะใช้ int แทนจำนวนเต็มหรือสองเท่าแทนที่จะเป็นสองเท่า สิ่งนี้จะช่วยให้ JVM เก็บค่าไว้บนสแต็กเพื่อลดการใช้หน่วยความจำและจัดการได้อย่างมีประสิทธิภาพมากขึ้น
8. พยายามหลีกเลี่ยง BigInteger และ BigDecimal
เนื่องจากเราได้พูดถึงประเภทข้อมูลลองดูที่ BigInteger และ BigDecimal โดยเฉพาะอย่างยิ่งหลังเป็นที่นิยมเนื่องจากมีความแม่นยำสูง แต่มีราคา
BigInteger และ BigDecimal ต้องการหน่วยความจำมากกว่าความยาวหรือสองเท่าและลดความเร็วในการคำนวณทั้งหมดได้อย่างมาก ดังนั้นหากคุณต้องการความแม่นยำเป็นพิเศษหรือตัวเลขของคุณเกินระยะยาวคุณควรคิดสองครั้งก่อนที่จะทำ นี่อาจเป็นสถานที่เดียวที่คุณต้องเปลี่ยนปัญหาการปรับปรุงประสิทธิภาพโดยเฉพาะอย่างยิ่งเมื่อคุณใช้อัลกอริทึมทางคณิตศาสตร์
9. ก่อนอื่นตรวจสอบระดับบันทึกปัจจุบัน
ข้อเสนอแนะนี้ชัดเจน แต่น่าเสียดายที่คุณจะพบว่ารหัสจำนวนมากไม่สนใจ ก่อนที่จะสร้างข้อความการดีบักคุณควรตรวจสอบระดับบันทึกปัจจุบันก่อน
นี่คือสองตัวอย่างเพื่อแสดงให้เห็นว่าคุณไม่ควรทำสิ่งนี้
// อย่าทำ thislog.debug ("ผู้ใช้ [" + ชื่อผู้ใช้ + "] เรียกว่าเมธอด x ด้วย [" + i + "]"); // หรือ thislog.debug (string.format ("ผู้ใช้ [%s] เรียกเมธอด x ด้วย [%d]" ชื่อผู้ใช้ i));ในทั้งสองกรณีคุณจะทำตามขั้นตอนทั้งหมดที่คุณต้องสร้างข้อความบันทึกโดยไม่ทราบว่า Framework Log ใช้ข้อความบันทึกหรือไม่ ก่อนที่จะสร้างข้อความการดีบักควรตรวจสอบระดับบันทึกปัจจุบันก่อน
10. ใช้ Apache Commons StringUtils.replace แทน String.replace
โดยทั่วไปวิธีการสตริงการฟื้นฟูทำงานได้ดีและมีประสิทธิภาพมากโดยเฉพาะอย่างยิ่งถ้าคุณใช้ Java 9 อย่างไรก็ตามหากแอปพลิเคชันต้องการการดำเนินการทดแทนจำนวนมากและคุณยังไม่ได้อัปเดตเป็นเวอร์ชัน Java ล่าสุด
ผู้สมัครคนหนึ่งคือวิธี Apache Commons Lang ของ Lang ดังที่ Lukas Eder อธิบายไว้ในโพสต์บล็อกเมื่อเร็ว ๆ นี้มันมีค่ามากกว่าสตริงวิธีการแทนที่ของ Java 8
มันต้องมีการเปลี่ยนแปลงเล็กน้อยเท่านั้น คุณเพียงแค่ต้องเพิ่มการพึ่งพา maven ลงในแอป pom.xml ของคุณสำหรับโครงการคอมมอนส์ของ Apache และแทนที่การโทรทั้งหมดเป็น String.retlace Methods ด้วยวิธี stringutils.replace
// แทนที่ thisttest.replace ("ทดสอบ", "การทดสอบอย่างง่าย"); // ด้วย thisstringutils.replace (ทดสอบ, "ทดสอบ", "การทดสอบอย่างง่าย");11. แคชทรัพยากรที่มีราคาแพงเช่นการเชื่อมต่อฐานข้อมูล
การแคชเป็นทางออกที่ได้รับความนิยมเพื่อหลีกเลี่ยงการดำเนินการซ้ำ ๆ ของโค้ดราคาแพงหรือใช้บ่อย แนวคิดทั่วไปนั้นง่ายมาก: มันถูกกว่ามากที่จะนำทรัพยากรเหล่านี้มาใช้ซ้ำมากกว่าสร้างทรัพยากรใหม่ซ้ำแล้วซ้ำอีก
ตัวอย่างทั่วไปคือการเชื่อมต่อฐานข้อมูลแคชในพูล การสร้างการเชื่อมต่อใหม่ต้องใช้เวลาและสามารถหลีกเลี่ยงได้หากการเชื่อมต่อที่มีอยู่ถูกนำกลับมาใช้ใหม่
ตัวอย่างอื่น ๆ สามารถพบได้ในภาษาชวาเอง ตัวอย่างเช่นวิธีการที่มีค่าของค่าแคชคลาสจำนวนเต็มระหว่าง -128 ถึง 127 คุณอาจพูดได้ว่าการสร้างจำนวนเต็มใหม่นั้นไม่แพงเกินไป แต่มักจะใช้และการแคชค่าที่ใช้กันมากที่สุดให้ประโยชน์ด้านประสิทธิภาพ
แต่เมื่อคุณคิดถึงการแคชโปรดจำไว้ว่าการใช้งานแคชอาจทำให้เกิดค่าใช้จ่ายได้ คุณต้องใช้หน่วยความจำพิเศษเพื่อจัดเก็บทรัพยากรที่นำกลับมาใช้ใหม่ได้ดังนั้นคุณอาจต้องจัดการแคชของคุณเพื่อเปิดใช้งานทรัพยากรในการเข้าถึงหรือลบทรัพยากรที่ล้าสมัย
ดังนั้นก่อนที่คุณจะเริ่มแคชทรัพยากรใด ๆ ให้แน่ใจว่าใช้บ่อย
สรุป
อย่างที่คุณเห็นการปรับปรุงประสิทธิภาพของแอปพลิเคชันของคุณบางครั้งไม่ต้องใช้งานมาก คำแนะนำส่วนใหญ่ในบทความนี้ต้องใช้ความพยายามเพียงเล็กน้อยในการใช้กับรหัส
แต่คำแนะนำที่สำคัญที่สุดคือมันเป็นภาษาที่ไม่ขึ้นกับการเขียนโปรแกรมมาก:
ลิงค์ต้นฉบับ: 11 เคล็ดลับการปรับแต่งประสิทธิภาพ Java อย่างง่าย (Editor/Wei Wei)