การวัดเวลาดำเนินการของฟังก์ชันใน R


282

มีวิธีที่เป็นมาตรฐานใน R ของการวัดเวลาดำเนินการของฟังก์ชั่นหรือไม่?

เห็นได้ชัดว่าฉันสามารถใช้system.timeก่อนและหลังการประหารชีวิตและจากนั้นนำความแตกต่างของสิ่งเหล่านั้น แต่ฉันอยากจะรู้ว่ามีวิธีการหรือฟังก์ชั่นที่ได้มาตรฐานหรือไม่


ฉันดูเหมือนจะจำได้ว่าฉันเคยใช้บางสิ่งบางอย่างเช่นด้านล่าง:

somesysfunction("myfunction(with,arguments)")
> Start time : 2001-01-01 00:00:00  # output of somesysfunction
> "Result" "of" "myfunction"        # output of myfunction
> End time : 2001-01-01 00:00:10    # output of somesysfunction
> Total Execution time : 10 seconds # output of somesysfunction

2
ฉันคิดว่าคุณมีproc.timeสาเหตุที่system.timeเป็นสิ่งที่คุณต้องการ
Marek

1
สำหรับฟังก์ชั่นที่ใหญ่กว่าRprofมันดี มันให้รายละเอียดของกระบวนการทั้งหมดในรหัสชิ้น / ฟังก์ชั่น
Rich Scriven

38
ผู้ใช้ R รายใหม่ค้นหาคำถามนี้ผ่านทาง Google: require(microbenchmark)ขณะนี้ (ตั้งแต่สองสามปีที่ผ่านมา) วิธีมาตรฐานของชุมชนในการทำสิ่งต่างๆ times <- microbenchmark( lm(y~x), glm(y~x), times=1e3); example(microbenchmark). นี้ไม่ได้สถิติเปรียบเทียบlmVS glm1000 พยายามมากกว่าsystem.timeการทดสอบเพียงครั้งเดียว
isomorphismes

ใช้res <- microbenchmark(your code1,your code2)แล้วprint(res)เพื่อดูตารางหรือggplot2::autoplot(res)เพื่อดู boxplot! การอ้างอิง
เทรวิส

คำตอบ:


253

อีกวิธีที่เป็นไปได้ในการทำเช่นนี้คือใช้ Sys.time ():

start.time <- Sys.time()
...Relevent codes...
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

ไม่ใช่วิธีที่สง่างามที่สุดในการทำเมื่อเทียบกับคำตอบด้านบน แต่เป็นวิธีการทำอย่างแน่นอน


14
นี่คือหน่วยความจำที่มีประสิทธิภาพมากขึ้นแล้ว system.time () ซึ่งคัดลอกข้อโต้แย้งได้อย่างมีประสิทธิภาพ เป็นสิ่งสำคัญเมื่อคุณจัดการกับข้อมูลที่พอดีกับแรมของคุณ
Adam Ryczkowski

2
สำหรับคนที่ใช้Sys.timeโปรดอ่านนี้สำหรับบางข้อแม้: รหัส R Timing กับ Sys.time ()
李哲源

1
system.time()เร็วขึ้นสำหรับฉัน ฉันคิดว่าคำตอบsystem.time()นั้นควรได้รับการยอมรับ!
Gwang-Jin Kim

นี่เป็นวิธีที่ฉันชอบที่จะรู้ว่าต้องใช้เวลานานแค่ไหนในการคำนวณแบบยาวที่ขนานกันในหลายแกน ในกรณีนี้เวลาของนาฬิกาแขวนที่วัดได้จากการโทรนี้มีความแม่นยำเพียงพอเนื่องจากคอมพิวเตอร์จะมีการคำนวณที่ยุ่งเหยิงมากกับคอร์ทั้งหมดที่คำนวณมากกว่าการทำอย่างอื่นและการคำนวณใช้เวลาหลายนาทีหรือหลายชั่วโมงจึงจะเสร็จสมบูรณ์ นี่เป็นกรณีการใช้งานที่เฉพาะเจาะจงมาก
Pablo Adames

186

ฟังก์ชั่นในตัวsystem.time()จะทำเช่นนั้น

ใช้เช่น: system.time(result <- myfunction(with, arguments))


1
สิ่งสำคัญที่ควรทราบคือsystem.time()มีอาร์กิวเมนต์gcFirstที่เป็นTRUEค่าเริ่มต้น ในมือข้างหนึ่งทำให้การวัดสามารถทำซ้ำได้มากขึ้น แต่สามารถสร้างค่าใช้จ่ายอย่างมีนัยสำคัญของเวลาทำงานทั้งหมด (ซึ่งไม่ได้วัดนอกหลักสูตร)
jakob-r

2
หน่วยนี้วัดอะไร? ตัวอย่างเช่นฉันเพิ่งวิ่งsystem.time(result <- myfunction(with, arguments))และได้รับ 187.564 เป็นผลลัพธ์ - นั่นคือในไม่กี่วินาทีหรืออะไร
zsad512


@ zsad512 ผมที่เหมาะสมให้แน่ใจว่าผู้ที่มีวินาที
Tapper

58

ในฐานะที่เป็น Andrie กล่าวว่าsystem.time()ทำงานได้ดี สำหรับฟังก์ชั่นระยะสั้นฉันชอบที่จะใส่replicate()มัน:

system.time( replicate(10000, myfunction(with,arguments) ) )

28
คุณควรใช้แพ็คเกจ microbenchmark เพราะไม่รวมค่าใช้จ่ายในการทำซ้ำในเวลา
hadley

37

วิธีการวัดเวลาดำเนินการที่ดีขึ้นเล็กน้อยคือใช้แพ็คเกจrbenchmark แพคเกจนี้ (ง่าย) ช่วยให้คุณระบุจำนวนครั้งที่จะทำซ้ำการทดสอบของคุณและมาตรฐานอ้างอิงควรจะเป็น

ดูคำถามที่เกี่ยวข้องได้ที่stats.stackexchange


6
Microbenchmark ดียิ่งขึ้นเพราะใช้ฟังก์ชั่นจับเวลาความแม่นยำสูงขึ้น
hadley

4
@hadley But rbenchmark นั้นใช้ง่ายกว่าในกรณีของการเปรียบเทียบ สำหรับฉัน microbenchmark ได้รับการอัพเกรด system.time rmicrobenchmark คือสิ่งที่เราจำเป็นต้อง :)
มาเร็ค

3
ผู้ดูแล microbenchmark ตอบสนองได้ค่อนข้างดี - ฉันคิดว่าเขาต้องการเพิ่มทุกอย่างที่คุณต้องการ
hadley

34

microbenchmark เป็นแพ็คเกจน้ำหนักเบา (~ 50kB) และเป็นวิธีมาตรฐานใน R มากขึ้นสำหรับการเปรียบเทียบหลายนิพจน์และฟังก์ชั่น:

microbenchmark(myfunction(with,arguments))

ตัวอย่างเช่น:

> microbenchmark::microbenchmark(log10(5), log(5)/log(10), times = 10000)
Unit: nanoseconds
           expr min lq    mean median uq   max neval cld
       log10(5)   0  0 25.5738      0  1 10265 10000   a
 log(5)/log(10)   0  0 28.1838      0  1 10265 10000

ทั้งสองนิพจน์ได้รับการประเมิน 10,000 ครั้งโดยมีเวลาดำเนินการเฉลี่ยอยู่ที่ประมาณ 25-30 ns


32

นอกจากนี้ยังมี proc.time()

คุณสามารถใช้ในทางเดียวกันว่าเป็นแต่มันช่วยให้คุณมีผลคล้ายกับSys.timesystem.time

ptm <- proc.time()
#your function here
proc.time() - ptm

ความแตกต่างที่สำคัญระหว่างการใช้

system.time({ #your function here })

เป็นproc.time()วิธีที่ยังคงใช้งานฟังก์ชั่นของคุณแทนการวัดเวลา ... และโดยวิธีการที่ฉันชอบที่จะใช้system.timeกับ{}ภายในเพื่อให้คุณสามารถวางชุดของสิ่งต่าง ๆ ...


25

แพ็คเกจ "tictoc" ช่วยให้คุณสามารถวัดเวลาดำเนินการได้ง่าย เอกสารที่อยู่ใน: https://cran.fhcrc.org/web/packages/tictoc/tictoc.pdf

install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
toc()

หากต้องการบันทึกเวลาที่ผ่านไปในตัวแปรคุณสามารถทำได้:

install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
exectime <- toc()
exectime <- exectime$toc - exectime$tic

18

แม้ว่าวิธีแก้ปัญหาอื่น ๆ จะมีประโยชน์สำหรับฟังก์ชั่นเดียว แต่ฉันขอแนะนำโค้ดต่อไปนี้โดยทั่วไปและมีประสิทธิภาพมากขึ้น:

Rprof(tf <- "log.log", memory.profiling = TRUE)
# the code you want to profile must be in between
Rprof (NULL) ; print(summaryRprof(tf))

2
ฉันยังไม่รู้เกี่ยวกับ Rprof มาจนถึงตอนนี้และมันยอดเยี่ยมมาก! บวกมันมาพร้อมกับฐาน R จึงไม่จำเป็นสำหรับแพคเกจพิเศษที่ไม่มีหรือmicrobenchmark profvis
Simon C.

ฉันสงสัยว่า rprof สามารถมองเห็นได้เช่นกันเช่นถ้าเราต้องการพล็อตเวลาสำหรับแต่ละรายการที่ทำโปรไฟล์หรือไม่
ซาวิร์อามิน

@ZawirAmin มีวิธีเพียงแค่ใช้ Rstudio >> เมนูโปรไฟล์
TPArrow

13

อีกวิธีที่ง่าย profvisแต่มีประสิทธิภาพมากที่จะทำเช่นนี้คือการใช้แพคเกจ ไม่เพียงแค่วัดเวลาประมวลผลของรหัสของคุณ แต่ให้รายละเอียดเจาะลึกสำหรับแต่ละฟังก์ชันที่คุณเรียกใช้ มันสามารถใช้สำหรับเงาเช่นกัน

library(profvis)

profvis({
  #your code here
})

คลิกที่นี่เพื่อดูตัวอย่าง


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.