В моем классе 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