system.time() และ proc.time()
วัดเวลาที่ผ่านไป เวลาในส่วนผู้ใช้ และเวลาระบบสำหรับนิพจน์ของ R
system.time() และ proc.time() เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องวัดประสิทธิภาพ
ก่อนปรับปรุงโค้ด คุณต้องวัดผลก่อน การคาดเดาว่าความช้าเกิดขึ้นที่ใดอาจทำให้เสียแรงโดยเปล่าประโยชน์ R มีเครื่องมือในตัวสำหรับจับเวลานิพจน์อย่างแม่นยำ
เครื่องมือหลักสามอย่างคือ system.time(), proc.time() และ Sys.time() แต่ละอย่างเหมาะกับจุดประสงค์ที่แตกต่างกันในการวิเคราะห์ประสิทธิภาพ
พื้นฐานของ system.time()
system.time(expr) จะประเมินนิพจน์และส่งคืนระยะเวลาที่ใช้ วิธีนี้เป็นวิธีที่ง่ายที่สุดในการจับเวลาการดำเนินการเดียวใน R
ผลลัพธ์เป็นออบเจ็กต์ของคลาส proc_time ซึ่งมีองค์ประกอบที่มีชื่อให้ตรวจสอบได้
result <- system.time({
x <- 1:1000000
total <- sum(x)
})
print(result)การอ่านค่าการจับเวลาสามค่า
system.time() ส่งคืนค่าห้าค่า แต่มีสามค่าที่สำคัญที่สุด:
- user — เวลา CPU ที่โค้ด R ใช้เอง
- sys — เวลา CPU ที่ระบบปฏิบัติการใช้แทน R
- elapsed — เวลาตามนาฬิกาจริง (จำนวนวินาทีจริงที่ผ่านไป)
โดยทั่วไปค่าที่คุณสนใจคือ elapsed ส่วน user + sys อาจมากกว่า elapsed ในเครื่องที่มีหลายแกนประมวลผล
t <- system.time(Sys.sleep(0.1))
cat('user :', t['user.self'], '
')
cat('sys :', t['sys.self'], '
')
cat('elapsed:', t['elapsed'], '
')ใช้ proc.time() เพื่อจับเวลาด้วยตนเอง
proc.time() ส่งคืนเวลา CPU และเวลาที่ผ่านไป ณ ปัจจุบันในรูปภาพรวมสถานะ หากบันทึกค่านี้ก่อนและหลังบล็อกโค้ด คุณก็สามารถจับเวลาช่วงโค้ดใด ๆ ได้
ลบภาพรวมสถานะตอนเริ่มออกจากภาพรวมสถานะตอนจบ เพื่อคำนวณเวลาที่ผ่านไปของส่วนนั้น
start <- proc.time()
for (i in 1:100000) sqrt(i)
end <- proc.time()
diff <- end - start
cat('elapsed:', diff['elapsed'], 'seconds
')องค์ประกอบของ proc.time()
proc.time() ส่งคืนเวกเตอร์ตัวเลขที่มีชื่อและมีสามองค์ประกอบ:
user.self— เวลา CPU ฝั่งผู้ใช้ของกระบวนการ Rsys.self— เวลา CPU ฝั่งระบบของกระบวนการ Relapsed— เวลาตามนาฬิกาจริงนับตั้งแต่เริ่ม R
ผลต่างระหว่างการเรียก proc.time() สองครั้งจะให้ช่วงเวลาที่มีความหมาย
pt <- proc.time()
cat('Names:', names(pt), '
')
cat('Values:', pt, '
')
cat('Class:', class(pt), '
')ใช้ Sys.time() เพื่อประทับเวลาตามนาฬิกาจริง
Sys.time() ส่งคืนวันที่และเวลาปัจจุบันเป็นออบเจ็กต์ POSIXct ต่างจาก proc.time() ตรงที่ให้เวลาประทับตามเหตุการณ์จริง ไม่ใช่เพียงการใช้ CPU
เหมาะสำหรับบันทึกว่าเหตุการณ์เกิดขึ้นเมื่อใด ไม่ใช่เพียงใช้เวลานานเท่าใด
start_time <- Sys.time()
cat('Start:', format(start_time), '
')
Sys.sleep(0.05)
end_time <- Sys.time()
cat('End :', format(end_time), '
')ใช้ difftime() เพื่อวัดช่วงเวลา
difftime(end, start, units='secs') คำนวณผลต่างระหว่างเวลาประทับ POSIXct สองค่า คุณสามารถเลือกหน่วยได้ ได้แก่ 'secs', 'mins', 'hours' และ 'days'
วิธีนี้ใช้คู่กับ Sys.time() ได้อย่างเป็นธรรมชาติ เพื่อแสดงผลการจับเวลาที่อ่านเข้าใจง่าย
t1 <- Sys.time()
x <- cumsum(1:500000)
t2 <- Sys.time()
delta <- difftime(t2, t1, units = 'secs')
cat('Time taken:', round(as.numeric(delta), 4), 'seconds
')จับเวลาในลูปด้วย replicate()
การวัดเวลาเพียงครั้งเดียวอาจแปรผันเนื่องจากการเก็บคืนหน่วยความจำหรือการจัดตารางเวลาของระบบปฏิบัติการ replicate(n, system.time(expr)['elapsed']) จะเรียกใช้นิพจน์หลายครั้งและส่งคืนเวกเตอร์ของเวลาที่ผ่านไป
การหาค่ามัธยฐานของเวลาที่วัดซ้ำจะให้ค่าประมาณที่เสถียรกว่า
times <- replicate(10, system.time({
x <- rnorm(10000)
mean(x)
})['elapsed'])
cat('Median elapsed:', median(times), 'seconds
')
cat('Range:', range(times), '
')การเปรียบเทียบแนวทางสองแบบ
ใช้ system.time() เพื่อเปรียบเทียบการนำงานเดียวกันไปใช้งานสองแบบโดยตรง รูปแบบนี้ช่วยยืนยันว่าแนวทางหนึ่งเร็วกว่า ก่อนที่คุณจะเลือกใช้แนวทางนั้น
n <- 100000
t_loop <- system.time({
result <- numeric(n)
for (i in seq_len(n)) result[i] <- i^2
})['elapsed']
t_vec <- system.time({
result <- seq_len(n)^2
})['elapsed']
cat('Loop :', t_loop, 's
')
cat('Vector :', t_vec, 's
')
cat('Speedup:', round(t_loop / max(t_vec, 1e-6), 1), 'x
')การจับเวลาการดำเนินการที่ซ้อนกัน
คุณสามารถซ้อนการเรียก system.time() หรือใช้จุดตรวจสอบจาก proc.time() ภายในกระบวนการทำงาน เพื่อระบุว่าขั้นตอนใดเป็นคอขวด
พิมพ์ผลต่างระหว่างช่วงเวลาระหว่างที่สคริปต์ทำงาน เพื่อสร้างลำดับเวลาของกระบวนการประมวลผลข้อมูล
p0 <- proc.time()
x <- rnorm(200000)
p1 <- proc.time()
y <- sort(x)
p2 <- proc.time()
z <- cumsum(y)
p3 <- proc.time()
cat('Generate:', (p1-p0)['elapsed'], 's
')
cat('Sort :', (p2-p1)['elapsed'], 's
')
cat('Cumsum :', (p3-p2)['elapsed'], 's
')เคล็ดลับการจับเวลาที่ใช้ได้จริง
โปรดคำนึงถึงแนวทางต่อไปนี้เมื่อจับเวลาโค้ด R:
- เรียกใช้โค้ดหนึ่งครั้งก่อนจับเวลา เพื่อเตรียม JIT และแคชไฟล์
- ใช้
gc()ก่อนจับเวลา เพื่อรีเซ็ตสถานะการเก็บคืนหน่วยความจำ - เลือกใช้ค่ามัธยฐานแทนค่าเฉลี่ยเมื่อวัดซ้ำ — ค่าผิดปกติจาก GC ทำให้ค่าเฉลี่ยเบี่ยงเบน
- จับเวลาเฉพาะคอขวด ไม่ใช่สคริปต์ทั้งหมด
gc() # clear garbage before timing
times <- replicate(5, system.time({
m <- matrix(rnorm(1000 * 1000), nrow = 1000)
crossprod(m)
})['elapsed'])
cat('Median:', median(times), 's
')ตรวจสอบด่วน: องค์ประกอบของ system.time()
องค์ประกอบใดของ system.time() ที่แสดงจำนวนวินาทีตามนาฬิกาจริงซึ่งผ่านไประหว่างการดำเนินการ
สรุปการจับเวลาประสิทธิภาพ
ขณะนี้คุณมีเครื่องมือจับเวลาสามอย่างที่เสริมกันใน R พื้นฐาน:
system.time(expr)— วิธีที่รวดเร็วที่สุดในการจับเวลานิพจน์หนึ่งรายการ ส่งคืนค่า user/sys/elapsedproc.time()— จับเวลาโดยใช้ภาพรวมสถานะสำหรับบล็อกโค้ดใด ๆSys.time()+difftime()— เวลาประทับตามนาฬิกาจริงและช่วงเวลาที่อ่านเข้าใจง่าย
ใช้ replicate() เพื่อให้ได้ค่ามัธยฐานของเวลาที่เสถียร ก่อนสรุปเกี่ยวกับประสิทธิภาพ
คำถามที่พบบ่อย
บทเรียน “system.time() และ proc.time()” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “system.time() และ proc.time()” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “system.time() และ proc.time()”
วัดเวลาที่ผ่านไป เวลาในส่วนผู้ใช้ และเวลาระบบสำหรับนิพจน์ของ R คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “system.time() และ proc.time()” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- system.time() และ proc.time()
- การวิเคราะห์ประสิทธิภาพโค้ดด้วย Rprof และ profvis
- เวกเตอร์ไรซ์เพื่อความเร็ว
- การเปรียบเทียบประสิทธิภาพด้วย microbenchmark