การระบุคอขวด
วัดผลก่อนปรับปรุงประสิทธิภาพ
การระบุคอขวด เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
วัดผล อย่าเดา
กฎข้อแรกของการปรับปรุงประสิทธิภาพคือ วัดผลก่อนปรับประสิทธิภาพ
การคาดเดาว่าโปรแกรม Java ใช้เวลาไปกับส่วนใดมักผิดพลาด คอมไพเลอร์ขณะทำงาน ตัวเก็บคืนหน่วยความจำ และแคชล้วนทำให้การคาดเดาลอย ๆ ใช้ไม่ได้ ให้สร้างโปรไฟล์ ค้นหาจุดที่ใช้ทรัพยากรมากที่สุดจริง ๆ แล้วแก้ไขจุดนั้น
นิยามคอขวด
คอขวดคือส่วนของระบบที่จำกัดปริมาณงานโดยรวมหรือความหน่วง
การปรับปรุงส่วนอื่นจะไม่ให้ประโยชน์ที่มองเห็นได้ กฎของอัมดาห์ทำให้เรื่องนี้ชัดเจนขึ้น: หาก 90% ของเวลาอยู่ในเมธอดเดียว การเร่งความเร็วของอีก 10% จะให้การปรับปรุงได้ไม่เกิน 11%
ความหน่วงเทียบกับปริมาณงาน
ตัดสินใจก่อนว่าคุณกำลังปรับปรุงสิ่งใด:
- ความหน่วง — คำขอหนึ่งรายการใช้เวลานานเท่าใด
- ปริมาณงาน — มีคำขอกี่รายการต่อวินาที
สองสิ่งนี้ต้องแลกกัน การประมวลผลเป็นชุดช่วยเพิ่มปริมาณงาน แต่อาจเพิ่มความหน่วงต่อคำขอได้ ทราบเป้าหมายของคุณก่อนปรับแต่ง
การจับเวลาตามนาฬิกาจริง
การวัดที่หยาบที่สุดคือจับเวลาตามนาฬิกาจริงรอบบล็อกโค้ดด้วย System.nanoTime()
วิธีนี้มีประโยชน์สำหรับการตรวจสอบความสมเหตุสมผลเบื้องต้น แต่รวมเวลาการอุ่นเครื่องของคอมไพเลอร์ขณะทำงาน การหยุดชั่วคราวของการเก็บคืนหน่วยความจำ และความแปรปรวนจากการจัดตารางของ OS ด้วย ดังนั้นควรระมัดระวังเมื่อตีความตัวเลขเพียงค่าเดียว
public class Main {
public static void main(String[] args) {
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 10_000_000; i++) sum += i;
long elapsed = System.nanoTime() - start;
System.out.println("Sum: " + sum);
System.out.println("Elapsed ms: " + (elapsed / 1_000_000.0));
}
}ระวังการอุ่นเครื่องคอมไพเลอร์ขณะทำงาน
Java เริ่มจากการแปลความหมายไบต์โค้ด จากนั้นคอมไพเลอร์ขณะทำงานจะคอมไพล์เมธอดที่ทำงานหนักเป็นโค้ดเครื่อง
ดังนั้นการทำงานครั้งแรก ๆ ของเมธอดจึงช้ากว่าการทำงานในภายหลังมาก การวนซ้ำเพื่อจับเวลาแบบง่าย ๆ จะวัดช่วงอุ่นเครื่องเป็นส่วนใหญ่ การทดสอบประสิทธิภาพจริงจะอุ่นเครื่องก่อน แล้วจึงวัดสถานะคงที่ ซึ่งเป็นสิ่งที่ JMH ทำให้คุณโดยอัตโนมัติ
ผูกกับ CPU เทียบกับผูกกับ IO
จัดประเภทของคอขวด:
- ผูกกับ CPU — เธรดกำลังคำนวณอย่างต่อเนื่อง แกนประมวลผลทำงานเต็มกำลัง
- ผูกกับ IO — เธรดกำลังรอดิสก์ เครือข่าย หรือฐานข้อมูล
เครื่องมือวิเคราะห์ประสิทธิภาพจะแยกสิ่งเหล่านี้เป็นเวลาที่ใช้บน CPU กับเวลาที่ถูกบล็อกหรือรอ วิธีแก้แตกต่างกันโดยสิ้นเชิง: ใช้อัลกอริทึมที่เร็วขึ้น หรือเพิ่มการทำงานพร้อมกันและลดรอบการติดต่อไปกลับ
การสุ่มตัวอย่างเทียบกับการใส่เครื่องมือวัด
กลยุทธ์การสร้างโปรไฟล์มีสองแบบ:
- การสุ่มตัวอย่าง — จับภาพร่องรอยสแตกเป็นระยะ มีค่าใช้จ่ายต่ำและอาศัยหลักสถิติ
- การใส่เครื่องมือวัด — เพิ่มตัวนับลงในทุกเมธอด ให้ผลแม่นยำ แต่มีค่าใช้จ่ายสูงและอาจทำให้เวลาที่วัดคลาดเคลื่อน
สำหรับระบบจริง ควรเลือกการสุ่มตัวอย่างที่มีค่าใช้จ่ายต่ำ เช่น เครื่องบันทึกการทำงานของ Java
หน่วยความจำในฐานะคอขวด
บ่อยครั้งต้นทุนที่แท้จริงคือการจัดสรรหน่วยความจำ ไม่ใช่การคำนวณ การสร้างออบเจ็กต์ทิ้งไปมามากเกินไปจะกระตุ้นการเก็บคืนหน่วยความจำบ่อยครั้ง ทำให้เสียกำลังของ CPU และเพิ่มการหยุดชั่วคราว
ติดตามอัตราการจัดสรรหน่วยความจำและเวลาที่ใช้ในการเก็บคืนหน่วยความจำ การลดการจัดสรรหน่วยความจำในลูปที่ทำงานหนักมักให้ผลดีกว่าการปรับแต่งการคำนวณเล็ก ๆ น้อย ๆ
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// Allocation-heavy: a new String each iteration
List<String> garbage = new ArrayList<>();
for (int i = 0; i < 5; i++) {
garbage.add("item-" + i);
}
System.out.println("Allocated " + garbage.size() + " strings");
System.out.println("In a hot loop, this churn drives GC pressure");
}
}ค้นหาด้านบนสุดของสแตก
เครื่องมือวิเคราะห์แบบสุ่มตัวอย่างจะแสดงรายการเมธอดที่จัดอันดับตามความถี่ที่ปรากฏบนสแตกของ CPU ซึ่งก็คือเวลาที่เมธอดใช้เอง
เมธอดที่อยู่บนสุดคือผู้สมัครที่ควรตรวจสอบ แต่ต้องยืนยันว่าเมธอดนั้นอยู่บนเส้นทางวิกฤตหรือไม่ เมธอดที่ทำงานหนักซึ่งทำงานอยู่ในตัวบันทึกระบบเบื้องหลังอาจไม่ส่งผลต่อความหน่วงที่ผู้ใช้พบ
สร้างค่าฐาน
ก่อนเปลี่ยนแปลงสิ่งใด ให้บันทึกการวัดค่าฐานภายใต้ภาระงานที่ใกล้เคียงการใช้งานจริง
หลังการเปลี่ยนแปลงแต่ละครั้ง ให้วัดซ้ำและเปรียบเทียบ หากไม่มีค่าฐาน คุณจะพิสูจน์ไม่ได้ว่าการปรับปรุงนั้นช่วยได้ และการปรับปรุงหลายอย่างกลับทำให้แย่ลง เปลี่ยนทีละอย่าง
สร้างโพรไฟล์ภายใต้ภาระงานที่สมจริง
คอขวดที่พบในแล็ปท็อปที่ไม่มีภาระงาน อาจไม่ใช่จุดที่สร้างปัญหาในระบบจริง
- ใช้ขนาดข้อมูลและการทำงานพร้อมกันที่เป็นตัวแทนของระบบจริง
- จำลองภาระงานที่มีความสำคัญต่อผู้ใช้จริง
การทดสอบขนาดเล็กแบบสังเคราะห์อาจชี้ไปยังเมธอดที่ไม่เกี่ยวข้องเมื่อขยายขนาดระบบ ควรสร้างโพรไฟล์ตรงจุดที่เกิดปัญหาจริง
ตรวจสอบอย่างรวดเร็ว
เหตุใดการจับเวลาเมธอด Java เพียงครั้งเดียวแบบตรงไปตรงมาโดยใช้ System.nanoTime() จึงมักทำให้เข้าใจผิด
สรุป
การค้นหาคอขวดอย่างมีระเบียบ:
- วัดผลก่อนปรับให้เหมาะสม สัญชาตญาณอาจหลอกคุณได้
- กำหนดเป้าหมาย: เวลาแฝงหรือปริมาณงาน
- จำแนกว่าจำกัดด้วย CPU หรือจำกัดด้วย IO และติดตามการเก็บคืนหน่วยความจำกับการจัดสรรหน่วยความจำ
- เลือกใช้เครื่องมือสร้างโพรไฟล์แบบ สุ่มตัวอย่างที่มีค่าใช้จ่ายต่ำ
- ระวังช่วงอุ่นเครื่องของการคอมไพล์ขณะทำงาน สร้าง ค่าพื้นฐาน และเปลี่ยนทีละอย่าง
คำถามที่พบบ่อย
บทเรียน “การระบุคอขวด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การระบุคอขวด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การระบุคอขวด”
วัดผลก่อนปรับปรุงประสิทธิภาพ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การระบุคอขวด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ