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

การเขียนการวัดประสิทธิภาพ

@Benchmark และโหมดต่าง ๆ

การเขียนการวัดประสิทธิภาพ เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

การเขียน Benchmark

Benchmark ของ JMH เป็นเพียงเมธอดที่มีคำอธิบายประกอบ @Benchmark อยู่ภายในคลาสทั่วไป ตัวประมวลผลคำอธิบายประกอบของ JMH จะสร้างเครื่องมือรองรับรอบเมธอดนั้น บทเรียนนี้ครอบคลุมคำอธิบายประกอบที่กำหนดว่าจะวัดอะไรและวัดอย่างไร

คำอธิบายประกอบ @Benchmark

กำกับเมธอดสาธารณะใด ๆ ด้วย @Benchmark แล้ว JMH จะเรียกใช้เมธอดนั้นซ้ำ ๆ พร้อมจับเวลาการเรียกแต่ละครั้ง ควรส่งคืนค่าผลลัพธ์ของเมธอด ไม่ใช่ทิ้งค่า เพื่อให้ JMH นำไปใช้ได้

คลาส Benchmark ขั้นต่ำ

นี่คือโครงสร้างของ Benchmark การนำเข้าอยู่ใน org.openjdk.jmh.annotations.* เนื่องจาก JMH ไม่ได้อยู่ในเส้นทางคลาสของตัวเรียกใช้งานนี้ ตัวอย่างนี้จึงมีไว้เพื่อประกอบคำอธิบายเท่านั้น

import org.openjdk.jmh.annotations.Benchmark;

public class StringBench {
    @Benchmark
    public String concat() {
        return "foo" + System.nanoTime();
    }
}

โหมด Benchmark

@BenchmarkMode จะเลือกรายการที่รายงาน:

  • ปริมาณงาน — จำนวนการดำเนินการต่อหน่วยเวลา (ค่ายิ่งสูงยิ่งดี)
  • AverageTime — เวลาต่อการดำเนินการ (ค่ายิ่งต่ำยิ่งดี)
  • SampleTime — การกระจายของเวลา (ค่าตำแหน่งเปอร์เซ็นไทล์)
  • SingleShotTime — การเรียกใช้หนึ่งครั้ง เหมาะสำหรับการเริ่มต้นแบบยังไม่มีการปรับให้เหมาะสม
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    public int work() {
        return 2 + 2;
    }
}

การเลือกหน่วยผลลัพธ์

@OutputTimeUnit จะกำหนดหน่วยเวลาในรายงานเพื่อให้ตัวเลขอ่านง่าย สำหรับการดำเนินการที่รวดเร็ว นาโนวินาทีเหมาะสมกว่า ส่วนการดำเนินการที่ช้า มิลลิวินาทีจะเหมาะกว่า

import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int work() {
        return 42;
    }
}

การส่งคืนผลลัพธ์

ให้ส่งคืนผลลัพธ์ของงานเสมอ JMH จะป้อนค่าที่ส่งคืนทุกค่าเข้าสู่แบล็กโฮลโดยอัตโนมัติ เพื่อป้องกันการลบโค้ดที่ไม่มีการใช้งาน การ Benchmark แบบ void ที่คำนวณแล้วทิ้งผลลัพธ์ถือเป็นข้อผิดพลาดที่พบได้บ่อย

ค่าเริ่มต้นของคำอธิบายประกอบ

คำอธิบายประกอบสามารถอยู่ที่เมธอดหรือทั้งคลาสก็ได้ คำอธิบายประกอบระดับคลาสจะมีผลกับ @Benchmark ทุกตัวในคลาสนั้น ทำให้การตั้งค่ายังคงเป็นไปตามหลัก DRY เมื่อมี Benchmark ที่เกี่ยวข้องกันหลายรายการ

การแยกกระบวนการ

@Fork(n) จะเรียกใช้ Benchmark ในกระบวนการ JVM ใหม่จำนวน n กระบวนการ การแยกกระบวนการจะทำให้การทำงานแต่ละครั้งไม่ถูกรบกวนจากข้อมูลประวัติของคอมไพเลอร์แบบทันเวลาที่ Benchmark ก่อนหน้าสร้างไว้ จึงช่วยให้ทำซ้ำผลลัพธ์ได้ดีขึ้น ค่าเริ่มต้นคือหนึ่งกระบวนการ

import org.openjdk.jmh.annotations.*;

@Fork(2)
public class Bench {
    @Benchmark
    public long now() {
        return System.nanoTime();
    }
}

การเรียกใช้ตัวรัน

คุณเริ่ม Benchmark ได้ผ่าน main ที่กำหนดค่าออบเจ็กต์ Options และ Runner หรือผ่าน JAR ที่สร้างขึ้น คำสั่งนิพจน์ปกติของ include(...) จะเลือกว่าจะเรียกใช้ Benchmark ใด

import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.*;

public class Launcher {
    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
            .include("Bench")
            .build();
        new Runner(opt).run();
    }
}

การอ่านผลลัพธ์

JMH จะแสดงตารางที่มีชื่อ Benchmark โหมด จำนวนตัวอย่าง คะแนน ค่าความคลาดเคลื่อนของคะแนน และหน่วย ตัวอย่างเช่น Bench.work avgt 25 3.142 +/- 0.011 ns/op ค่า +/- คือช่วงความเชื่อมั่น

ทำให้ Benchmark มีจุดมุ่งหมายชัดเจน

Benchmark แต่ละรายการควรวัดเพียงสิ่งเดียว การรวมการเตรียมข้อมูล อินพุต/เอาต์พุต และการดำเนินการที่กำลังทดสอบไว้ด้วยกันจะทำให้ผลลัพธ์ไม่ชัดเจน ย้ายการเตรียมข้อมูลไปไว้ในเมธอด @Setup ซึ่งจะอธิบายร่วมกับสถานะ เพื่อจับเวลาเฉพาะส่วนที่ถูกเรียกใช้บ่อยเท่านั้น

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการเขียน Benchmark

สรุปทบทวน

คุณได้เรียนรู้วิธีเขียน Benchmark ของ JMH:

  • กำกับเมธอดด้วย @Benchmark และส่งคืนผลลัพธ์
  • @BenchmarkMode ใช้เลือกปริมาณงาน, AverageTime, SampleTime หรือ SingleShotTime
  • @OutputTimeUnit กำหนดหน่วยที่อ่านง่าย ส่วน @Fork แยกการทำงานแต่ละครั้งไว้ใน JVM ใหม่
  • เรียกใช้ด้วย ตัวรัน + ตัวเลือก หรือ JAR ที่สร้างขึ้น
  • ให้ Benchmark แต่ละรายการมุ่งเน้นที่ส่วนการทำงานที่ถูกเรียกใช้บ่อยเพียงส่วนเดียว

คำถามที่พบบ่อย

บทเรียน “การเขียนการวัดประสิทธิภาพ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเขียนการวัดประสิทธิภาพ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเขียนการวัดประสิทธิภาพ”

@Benchmark และโหมดต่าง ๆ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การเขียนการวัดประสิทธิภาพ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. เหตุใดจึงใช้ JMH
  2. การเขียนการวัดประสิทธิภาพ
  3. การอุ่นเครื่องและรอบการทำงาน
  4. การหลีกเลี่ยงการลบโค้ดที่ไม่ก่อผล
← กลับไปที่ Java Academy