Is it more efficient to declare helper functions outside the main function?

Viewed 152

When I debug step by step this kind of function:

foo <- function(x) {
  helper <- function(x) x^2
  2 * helper(x)
}

I see that the helper function definition is evaluated each time. Is it the same, when no in debug mode? Is it bad in terms of time execution?

2 Answers

You can try it yourself. I didn't see much of a difference. inside or outside was faster on different runs when I tried it.

library(microbenchmark)

foo1 <- function(x) {
  helper <- function(x) x^2
  2 * helper(x)
}

helper <- function(x) x^2
foo2 <- function(x) {
  2 * helper(x)
}

microbenchmark(
  inside = foo1(1:1000),
  outside = foo2(1:1000),
  times = 1000
)

Based on @John Coleman comment I have tried this:

library(microbenchmark)

foo1 <- function(x) {
  helper <- function(x) {
    nested_helper <- function(y) {
      depper_helper <- function(z) {
        z + z
      }
      3 * depper_helper(y)
    }
    nested_helper(x) ^ 2
  }
  2 * helper(x)
}


nested_helper <- function(y) {
  3 * depper_helper(y)
}
depper_helper <- function(z) {
  z + z
}
helper <- function(x) {
  nested_helper(x) ^ 2
}
foo2 <- function(x) {
  2 * helper(x)
}

microbenchmark(
  inside = foo1(1:1000),
  outside = foo2(1:1000),
  times = 1000000
)

I ran it two times and obtain the same results:

Unit: microseconds
    expr min  lq     mean median  uq     max neval
  inside 5.0 5.4 8.822796    5.8 8.5 50905.9 1e+06
 outside 4.9 5.2 8.559778    5.6 8.3 47797.3 1e+06

Inside definition seems a little bit slower but not in a significant way. There must be some kind of optimization by the JIT compiler. I would like confirmation of this.

Related