Медленная отправка метода S4?

В моем классе S4 есть метод, который вызывается много раз. Я заметил, что время выполнения намного медленнее, чем было бы, если бы подобная функция была вызвана независимо. Поэтому я добавил слот с типом «функция» в свой класс и использовал эту функцию вместо метода. В приведенном ниже примере показаны два способа сделать это, и оба они работают намного быстрее, чем соответствующий метод. Кроме того, в примере предполагается, что более низкая скорость метода не связана с тем, что метод должен извлекать данные из класса, поскольку функции работают быстрее, даже если они это делают.

Конечно, такой способ не идеален. Интересно, есть ли способ ускорить отправку метода. Какие-либо предложения?

    setClass(Class = "SpeedTest", 
      representation = representation(
        x = "numeric",
        foo1 = "function",
        foo2 = "function"
      )
    )

    speedTest <- function(n) {
      new("SpeedTest",
        x = rnorm(n),
        foo1 = function(z) sqrt(abs(z)),
        foo2 = function() {}
      )
    }

    setGeneric(
      name = "method.foo",
      def = function(object) {standardGeneric("method.foo")}
    )
    setMethod(
      f = "method.foo", 
      signature = "SpeedTest",
      definition = function(object) {
        sqrt(abs(object@x))
      }
    )

    setGeneric(
      name = "create.foo2",
      def = function(object) {standardGeneric("create.foo2")}
    )
    setMethod(
      f = "create.foo2", 
      signature = "SpeedTest",
      definition = function(object) {
        z <- object@x
        object@foo2 <- function() sqrt(abs(z))

        object
      }
    )

    > st <- speedTest(1000)
    > st <- create.foo2(st)
    > 
    > iters <- 100000
    > 
    > system.time(for (i in seq(iters)) method.foo(st)) # slowest by far
       user  system elapsed 
       3.26    0.00    3.27 

    > # much faster 
    > system.time({foo1 <- st@foo1; x <- st@x; for (i in seq(iters)) foo1(x)}) 
       user  system elapsed 
      1.47    0.00    1.46 

    > # retrieving st@x instead of x does not affect speed
    > system.time({foo1 <- st@foo1; for (i in seq(iters)) foo1(st@x)}) 
       user  system elapsed 
       1.47    0.00    1.49 

    > # same speed as foo1 although no explicit argument
    > system.time({foo2 <- st@foo2; for (i in seq(iters)) foo2()}) 
       user  system elapsed 
       1.44    0.00    1.45 

     # Cannot increase speed by using a lambda to "eliminate" the argument of method.foo
     > system.time({foo <- function() method.foo(st); for (i in seq(iters)) foo()})  
        user  system elapsed 
        3.28    0.00    3.29

Ответы на вопрос(2)

Ваш ответ на вопрос