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

การเปรียบเทียบประสิทธิภาพด้วย microbenchmark

เปรียบเทียบการนำไปใช้งานหลายรูปแบบทางสถิติด้วย microbenchmark()

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

เหตุใดจึงต้องใช้ microbenchmark

system.time() มีความละเอียดระดับมิลลิวินาทีและไม่น่าเชื่อถือสำหรับการดำเนินการที่รวดเร็ว แพ็กเกจ microbenchmark จะประเมินนิพจน์หลายร้อยครั้ง จัดการช่วงอุ่นเครื่อง และรายงานสถิติที่มีความละเอียดระดับนาโนวินาที จึงเป็นเครื่องมือที่เหมาะสมสำหรับเปรียบเทียบการใช้งานที่คล้ายกัน

การใช้งาน microbenchmark เบื้องต้น

ส่งนิพจน์ที่ตั้งชื่อแล้วให้กับ microbenchmark() ชื่ออาร์กิวเมนต์แต่ละตัวจะกลายเป็นป้ายกำกับในผลลัพธ์ อาร์กิวเมนต์ times ใช้กำหนดจำนวนครั้งที่ประเมินนิพจน์แต่ละรายการ

# library(microbenchmark)
# x <- 1:10000
#
# microbenchmark(
#   loop = {
#     s <- 0
#     for (v in x) s <- s + v
#   },
#   vectorized = sum(x),
#   times = 200L
# )

การเลือกค่าอาร์กิวเมนต์ times

การทำซ้ำมากขึ้นให้ค่าประมาณที่เสถียรมากขึ้น แต่ใช้เวลานานขึ้น แนวทางทั่วไปมีดังนี้:

  • นิพจน์ที่เร็ว (ระดับไมโครวินาที): times = 1000L หรือมากกว่า
  • ระดับปานกลาง (มิลลิวินาที): times = 100L
  • นิพจน์ที่ช้า (วินาที): times = 10L หรือน้อยกว่า

ค่าเริ่มต้นคือ times = 100L ซึ่งเป็นจุดเริ่มต้นที่ดี

# library(microbenchmark)
# microbenchmark(
#   fast_op = sqrt(2),
#   times = 10000L   # many reps for a nanosecond-scale operation
# )
# microbenchmark(
#   slow_op = sort(rnorm(1e6)),
#   times = 10L      # fewer reps for second-scale operation
# )

การระบุอาร์กิวเมนต์ unit

ใช้อาร์กิวเมนต์ unit เพื่อแสดงผลลัพธ์ในหน่วยที่อ่านได้สะดวก:

  • 'ns' — นาโนวินาที (สำหรับการดำเนินการที่เร็วมาก)
  • 'us' — ไมโครวินาที
  • 'ms' — มิลลิวินาที
  • 's' — วินาที
  • 'relative' — อัตราส่วนเมื่อเทียบกับนิพจน์ที่เร็วที่สุด
# library(microbenchmark)
# x <- runif(1000)
#
# microbenchmark(
#   sapply_sqrt = sapply(x, sqrt),
#   vectorized  = sqrt(x),
#   times = 500L,
#   unit = 'us'   # display in microseconds
# )

การตีความผลลัพธ์สรุป

microbenchmark จะแสดงตารางสรุปที่มีคอลัมน์ต่อไปนี้:

  • min — การทำงานครั้งเดียวที่เร็วที่สุด
  • lq / mean / median / uq — ควอร์ไทล์ล่าง ค่าเฉลี่ย มัธยฐาน และควอร์ไทล์บน
  • max — การทำงานครั้งเดียวที่ช้าที่สุด
  • neval — จำนวนครั้งที่ประเมิน

ใช้ median เป็นตัวชี้วัดหลักในการเปรียบเทียบ เพราะทนต่อการหยุดชั่วคราวของ GC ที่เกิดขึ้นเป็นครั้งคราว ซึ่งทำให้ค่า max และค่าเฉลี่ยสูงขึ้น

# Example summary output (unit: microseconds):
#
#         expr    min     lq   mean  median    uq    max neval
#         loop 1203.1 1245.3 1301.7  1262.4 1310.1 2100.8   100
#   vectorized    2.1    2.3    2.9     2.4    2.6   18.3   100
#
# => vectorized is ~525x faster at median
cat('Always compare medians, not means, for microbenchmark results
')

summary() กับออบเจ็กต์ microbenchmark

การเรียกใช้ summary(mb) กับผลลัพธ์ microbenchmark ที่จัดเก็บไว้ จะคืนค่าดาต้าเฟรมที่สามารถตรวจสอบด้วยโปรแกรมได้ นอกจากนี้ยังเปลี่ยนค่า unit ในการเรียกใช้ summary ได้ด้วย

# library(microbenchmark)
# x <- rnorm(5000)
# mb <- microbenchmark(
#   vapply_abs  = vapply(x, abs, numeric(1)),
#   base_abs    = abs(x),
#   times = 200L
# )
# s <- summary(mb, unit = 'ms')
# print(s[, c('expr', 'min', 'median', 'max')])

autoplot() สำหรับการเปรียบเทียบด้วยภาพ

autoplot(mb) ใช้ ggplot2 เพื่อวาดกราฟไวโอลินหรือกราฟกล่องของการกระจายเวลาสำหรับนิพจน์ต่าง ๆ ทำให้เห็นได้ง่ายไม่เพียงความแตกต่างของค่ามัธยฐาน แต่ยังรวมถึงความแปรปรวนและการทับซ้อนกันระหว่างทางเลือกต่าง ๆ

# library(microbenchmark)
# library(ggplot2)
#
# x <- 1:50000
# mb <- microbenchmark(
#   loop   = { s <- 0; for (v in x) s <- s + v },
#   vapply = vapply(x, identity, numeric(1)),
#   vec    = sum(x),
#   times  = 100L
# )
# autoplot(mb)  # opens ggplot2 violin chart

การเปรียบเทียบลูปกับ vapply และ sapply

การทดสอบประสิทธิภาพแบบคลาสสิกคือการใช้ฟังก์ชันกับสมาชิกทีละตัวด้วยลูป for, sapply() หรือ vapply() โดย vapply() เร็วกว่า sapply() เพราะจองพื้นที่สำหรับเวกเตอร์ผลลัพธ์ล่วงหน้า ทั้งสองวิธีช้ากว่าโค้ดที่ประมวลผลแบบเวกเตอร์ทั้งหมด

# library(microbenchmark)
# x <- runif(5000, 1, 100)
#
# mb <- microbenchmark(
#   for_loop = {
#     r <- numeric(length(x))
#     for (i in seq_along(x)) r[i] <- log(x[i])
#   },
#   sapply_log  = sapply(x, log),
#   vapply_log  = vapply(x, log, numeric(1)),
#   vec_log     = log(x),
#   times = 200L, unit = 'us'
# )
# print(mb)

ตรวจสอบความถูกต้องก่อน

ก่อนทดสอบประสิทธิภาพ ให้ตรวจสอบว่านิพจน์ทั้งหมดคืนค่าผลลัพธ์ที่เหมือนกัน การใช้งานที่เร็วกว่าแต่ไม่ถูกต้องย่อมไม่มีประโยชน์ ใช้ identical() หรือ all.equal() เพื่อเปรียบเทียบผลลัพธ์

# x <- runif(1000)
# r1 <- sapply(x, sqrt)
# r2 <- sqrt(x)
# r3 <- vapply(x, sqrt, numeric(1))
#
# stopifnot(isTRUE(all.equal(r1, r2)))
# stopifnot(isTRUE(all.equal(r1, r3)))
# cat('All three produce identical results -- safe to benchmark
')
cat('Always verify correctness before comparing speed
')

การทดสอบประสิทธิภาพด้วยอาร์กิวเมนต์ setup

ใช้อาร์กิวเมนต์ setup เพื่อเรียกใช้โค้ดหนึ่งครั้งก่อนนิพจน์ที่จับเวลา วิธีนี้ช่วยไม่ให้เวลาสร้างข้อมูลถูกรวมอยู่ในการทดสอบ เมื่อสิ่งที่ต้องการวัดไม่ใช่การสร้างข้อมูล

# library(microbenchmark)
#
# microbenchmark(
#   sort_base  = sort(x),
#   sort_order = x[order(x)],
#   setup = { x <- rnorm(10000) },
#   times = 100L
# )
# Each iteration refreshes x via setup, then times sort_base and sort_order

การรายงานผลการทดสอบประสิทธิภาพในการวิเคราะห์

เมื่อแบ่งปันผลการทดสอบประสิทธิภาพ ให้รายงานข้อมูลต่อไปนี้เสมอ:

  • เวอร์ชันและแพลตฟอร์มของ R
  • เวอร์ชันของแพ็กเกจ
  • ค่าของ times ที่ใช้
  • ขนาดข้อมูลที่นำมาทดสอบประสิทธิภาพ

เวลาในการทำงานไม่สามารถนำไปใช้เปรียบเทียบข้ามเครื่องได้โดยตรง ดังนั้นเมื่อเปรียบเทียบการใช้งาน ให้รายงานอัตราส่วนแทนค่าที่แน่นอน

cat('R version    :', R.version$version.string, '
')
cat('Platform     :', R.version$platform, '
')
cat('Logical cores:', parallel::detectCores(), '
')

ตรวจสอบอย่างรวดเร็ว: ตัวชี้วัดของ microbenchmark

สถิติสรุปใดจากผลลัพธ์ของ microbenchmark ที่น่าเชื่อถือที่สุดสำหรับเปรียบเทียบการใช้งานสองแบบ

ทบทวน microbenchmark

microbenchmark เป็นเครื่องมือมาตรฐานสำหรับการทดสอบประสิทธิภาพระดับย่อยอย่างเข้มงวดใน R:

  • ส่งนิพจน์ที่ตั้งชื่อแล้ว และกำหนด times เพื่อควบคุมจำนวนการทำซ้ำ
  • ใช้ unit = 'us' หรือ 'ms' เพื่อให้ผลลัพธ์อ่านง่าย
  • เปรียบเทียบค่า มัธยฐาน เพราะทนต่อค่าผิดปกติจาก GC
  • ใช้ autoplot() เพื่อแสดงการกระจายของเวลาเป็นภาพ
  • ตรวจสอบความถูกต้องด้วย all.equal() ก่อนทดสอบประสิทธิภาพ

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

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

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

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

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

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

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

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

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

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

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

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

  1. system.time() และ proc.time()
  2. การวิเคราะห์ประสิทธิภาพโค้ดด้วย Rprof และ profvis
  3. เวกเตอร์ไรซ์เพื่อความเร็ว
  4. การเปรียบเทียบประสิทธิภาพด้วย microbenchmark
← กลับไปที่ R Academy