Timing R code with Sys.time()

后端 未结 1 657
青春惊慌失措
青春惊慌失措 2021-01-11 10:41

I can run a piece of code for 5 or 10 seconds using the following code:

period <- 10  ## minimum time (in seconds) that the loop should run for
tm <- S         


        
相关标签:
1条回答
  • 2021-01-11 11:27

    As soon as elapsed time exceeds 1 minute, the default unit changes from seconds to minutes. So you want to control the unit:

    while (difftime(Sys.time(), tm, units = "secs")[[1]] < period)
    

    From ?difftime

     If ‘units = "auto"’, a suitable set of units is chosen, the
     largest possible (excluding ‘"weeks"’) in which all the absolute
     differences are greater than one.
    
     Subtraction of date-time objects gives an object of this class, by
     calling ‘difftime’ with ‘units = "auto"’.
    

    Alternatively use proc.time, which measures various times ("user", "system", "elapsed") since you started your R session in seconds. We want "elapsed" time, i.e., the wall clock time, so we retrieve the 3rd value of proc.time().

    period <- 10
    tm <- proc.time()[[3]]
    while (proc.time()[[3]] - tm < period) print(proc.time())
    

    If you are confused by the use of [[1]] and [[3]], please consult:

    • How do I extract just the number from a named number (without the name)?
    • How to get a matrix element without the column name in R?

    Let me add some user-friendly reproducible examples. Your original code with print inside a loop is quite annoying as it prints thousands of lines onto the screen. I would use Sys.sleep.

    test.Sys.time <- function(sleep_time_in_secs) {
      t1 <- Sys.time()
      Sys.sleep(sleep_time_in_secs)
      t2 <- Sys.time()
      ## units = "auto"
      print(t2 - t1)
      ## units = "secs"
      print(difftime(t2, t1, units = "secs"))
      ## use '[[1]]' for clean output
      print(difftime(t2, t1, units = "secs")[[1]])
      }
    
    test.Sys.time(5)
    #Time difference of 5.005247 secs
    #Time difference of 5.005247 secs
    #[1] 5.005247
    
    test.Sys.time(65)
    #Time difference of 1.084357 mins
    #Time difference of 65.06141 secs
    #[1] 65.06141
    

    The "auto" units is very clever. If sleep_time_in_secs = 3605 (more than an hour), the default unit will change to "hours".

    Be careful with time units when using Sys.time, or you may be fooled in a benchmarking. Here is a perfect example: Unexpected results in benchmark of read.csv / fread. I had answered it with a now removed comment:

    You got a problem with time units. I see that fread is more than 20 times faster. If fread takes 4 seconds to read a file, read.csv takes 80 seconds = 1.33 minutes. Ignoring the units, read.csv is "faster".

    Now let's test proc.time.

    test.proc.time <- function(sleep_time_in_secs) {
      t1 <- proc.time()
      Sys.sleep(sleep_time_in_secs)
      t2 <- proc.time()
      ## print user, system, elapsed time
      print(t2 - t1)
      ## use '[[3]]' for clean output of elapsed time
      print((t2 - t1)[[3]])
      }
    
    test.proc.time(5)
    #   user  system elapsed 
    #  0.000   0.000   5.005 
    #[1] 5.005
    
    test.proc.time(65)
    #   user  system elapsed 
    #  0.000   0.000  65.057 
    #[1] 65.057
    

    "user" time and "system" time are 0, because both CPU and the system kernel are idle.

    0 讨论(0)
提交回复
热议问题