คอมไพล์โค้ดใน java 8 vs คอมไพล์โค้ดใน java 11
ขณะนี้เรามีโค้ดที่คอมไพล์ใน Java 8 แต่เรากำลังเรียกใช้งานนั้นบน Java 11 VM ตอนนี้เรากำลังพยายามย้ายโค้ดของเราไปที่ Java 11 compile time เช่นกัน สงสัยว่าการคอมไพล์โค้ดใน Java 8 เทียบกับโค้ดคอมไพล์ใน Java 11 มีประโยชน์หรือไม่เนื่องจากคอมไพเลอร์ทั้งสองจะสร้างไฟล์คลาสที่แตกต่างกัน (bytecode) หรือไม่? หนึ่งแตกต่างจากที่อื่นในแง่ของประสิทธิภาพอย่างไร?
คำตอบ
javacจะไม่ได้เป็นคอมไพเลอร์เพิ่มประสิทธิภาพดังนั้นโดยทั่วไปไม่ได้คาดหวังในการผลิต "เร็วขึ้น" bytecode จากรุ่นที่จะปล่อย การเพิ่มประสิทธิภาพเป็นงานของ JVM
ในขณะเดียวกัน, Java คอมไพเลอร์ไม่คุณสมบัติสนับสนุนภาษาใหม่และอาจสนับสนุนคุณสมบัติ JVM ใหม่ บางคนมีผลกระทบด้านประสิทธิภาพอย่างแท้จริง ตัวอย่างที่โดดเด่นที่สุดใน JDK 9 - JDK 11 มีดังต่อไปนี้
JEP 280: ระบุการต่อสายอักขระ (JDK 9)
JEP นี้เปลี่ยนวิธีการคอมไพล์นิพจน์การต่อสตริง ก่อน JDK 9
+นิพจน์สตริงถูกแปลเป็นnew StringBuilder().append()...append().toString();แม้ว่า JIT จะรับรู้เชนดังกล่าวและพยายามปรับให้เหมาะสมในรันไทม์ แต่การเพิ่มประสิทธิภาพนี้มีความเปราะบางและไม่ได้ผลตามที่คาดไว้เสมอไป การคอมไพล์การต่อสายอักขระด้วย
invokedynamicทำให้ JVM มีอิสระมากขึ้นในการสร้างโค้ดที่ดีขึ้น คุณสามารถดูคำอธิบายโดยละเอียดและเกณฑ์มาตรฐานได้ในบันทึกย่อของ JEP นี้JEP 181: Nest-based Access Control (JDK 11)
JEP นี้ช่วยแก้ปัญหาในการเข้าถึงสมาชิกส่วนตัวของคลาสที่ซ้อนกัน ก่อน JDK 11 Java Compiler สร้างวิธีการสะพานสังเคราะห์สำหรับพวกเขา ( ตัวอย่าง )
เมื่อมองแวบแรกสิ่งนี้ไม่เกี่ยวข้องกับประสิทธิภาพ อย่างไรก็ตามในกรณีเล็กน้อยวิธีการสังเคราะห์เพิ่มเติมอาจทำให้อินไลน์แตกได้เนื่องจากขีดจำกัดความลึก
Nest-Based Access Control ช่วยให้คลาส Nestmate สามารถเข้าถึงสมาชิกส่วนตัวของกันและกันได้โดยไม่ต้องใช้บริดจ์สังเคราะห์ซึ่งจะช่วยลดความเสี่ยงจากการลดประสิทธิภาพโดยไม่ได้ตั้งใจ
อัปเดต
ก่อนหน้านี้ฉันได้รวมJDK-8175883: การสร้าง Bytecode สำหรับ Enhanced สำหรับ Loopไว้ในรายการนี้ แต่ตามที่ @Holger สังเกตเห็นในความคิดเห็น "การเพิ่มประสิทธิภาพ" นี้ไม่ได้ผลจริง
สรุป
การเปลี่ยนแปลงใน Java Compiler ส่วนใหญ่เกี่ยวข้องกับคุณลักษณะของภาษา / JVM ใหม่ การเพิ่มประสิทธิภาพระดับ Bytecode ไม่ใช่เป้าหมาย อย่างไรก็ตามการเปลี่ยนแปลงบางอย่างอาจส่งผลต่อประสิทธิภาพการทำงาน (โดยอ้อม) ด้วย อย่างไรก็ตามประสิทธิภาพที่เป็นไปได้จากการคอมไพล์โค้ดใหม่มักจะมีขนาดเล็กมากจนคุณไม่ได้สังเกตเห็นมันในแอปพลิเคชันจริง