การเขียนการวัดประสิทธิภาพ
@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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เหตุใดจึงใช้ JMH
- การเขียนการวัดประสิทธิภาพ
- การอุ่นเครื่องและรอบการทำงาน
- การหลีกเลี่ยงการลบโค้ดที่ไม่ก่อผล