function in R that also returns the runtime itself

I know that Rprof () exists, but it seems to me rather inaccurate compared to microbenchmark(). However, if I want to use microbenchmark() I have to call the function 2 times, one to have the output from it and another to run the time from it (which seems to me quite unfeasible)

I don't know how to call the function only 1 time and have as response the normal output of it and also the very accurate runtime.

The function is not that, but follows a example of my problem:

teste <- function(x){

  Rprof()
  x <- x+2
  Rprof(NULL)

  return(summaryRprof())
}
guarda_x_e_tempo <- teste(2)

Or

teste <- function(x){
  x <- x+2
  return(x)
}
guarda_x <- teste(2)
guarda_tempo <- teste(2)
Author: Adenilson Junior, 2018-06-02

3 answers

See if the following is what you want.
The result of the function R base proc.time is obtained right at the first statement of the function teste and then subtracted from proc.time at the end.

teste <- function(x){
  ini <- proc.time()
  x <- x + 2
  list(result = x, tempo = proc.time() - ini)
}

guarda_x_e_tempo <- teste(2)

guarda_x_e_tempo
#$`result`
#[1] 4
#
#$tempo
#   user  system elapsed 
#      0       0       0

Now another, more time-consuming function.

teste2 <- function(x, n = 1e6){
  ini <- proc.time()
  for(i in seq_len(n)) x <- x + 2
  list(result = x, tempo = proc.time() - ini)
}

teste2(2)
#$`result`
#[1] 2000002
#
#$tempo
#   user  system elapsed 
#   0.08    0.00    0.08 
#

Another Way is for the expression to time in system.time. This allows you to time execution without modifying the functions.

teste3 <- function(x, n = 1e6){
  for(i in seq_len(n)) x <- x + 2
  x
}

system.time(teste3(2))
# usuário   sistema decorrido 
#   0.048     0.000     0.049
 1
Author: Rui Barradas, 2018-06-04 19:24:30

Adenilson, all right?

I believe the system function.time meets your need:

funcao_exemplo <- function(x) {
  print(x)
}

system.time(funcao_exemplo("Hello World"))
 2
Author: Antonio C. da Silva Júnior, 2018-06-04 14:51:17

The accuracy of microbenchmark is in running the functions several times thus avoiding being influenced by possible computer crashes that could affect the runtime. When you run the microbenchmark it runs by default 100X the function to be able to calculate mean, median , echo of runtimes.

That said, microbenchmark is not suitable for what you want to do.

I believe the other answers already have good solutions, but I think an elegant way to do that would be to create a function as follows:

crono <- function(f) {
  function(...) {
    exec_time <- system.time({res <- f(...)})
    list(
      exec_time = exec_time,
      res = res
    )
  }
}

We call this type of function Function Operators.

With it you can create versions of your functions that are timed, for example:

crono_mean <- crono(mean)
crono_mean(1:10000000)

Which would result in:

$exec_time
   user  system elapsed 
  0.034   0.018   0.061 

$res
[1] 5e+06
 2
Author: Daniel Falbel, 2018-06-07 12:27:24