0Pricing
Java Academy · บทเรียน

การระบุคอขวด

วัดผลก่อนปรับปรุงประสิทธิภาพ

การระบุคอขวด เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การระบุคอขวด
  2. Java Flight Recorder
  3. การวิเคราะห์ด้วย JDK Mission Control
  4. แฟล็กปรับแต่ง JVM ที่พบบ่อย
← กลับไปที่ Java Academy