การเปรียบเทียบประสิทธิภาพด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- system.time() และ proc.time()
- การวิเคราะห์ประสิทธิภาพโค้ดด้วย Rprof และ profvis
- เวกเตอร์ไรซ์เพื่อความเร็ว
- การเปรียบเทียบประสิทธิภาพด้วย microbenchmark