La mia classe S4 ha un metodo chiamato molte volte. Ho notato che il tempo di esecuzione è molto più lento di quanto sarebbe se una funzione simile fosse chiamata indipendentemente. Quindi ho aggiunto uno slot con tipo "function" alla mia classe e ho usato quella funzione al posto del metodo. L'esempio seguente mostra due modi per farlo, ed entrambi funzionano molto più velocemente del metodo corrispondente. Inoltre, l'esempio suggerisce che la velocità più bassa del metodo non è dovuta al fatto che il metodo deve recuperare i dati dalla classe, poiché le funzioni sono più veloci anche quando lo fanno.La spedizione del metodo S4 è lenta?
Ovviamente, questo modo di fare le cose non è l'ideale. Mi chiedo se c'è un modo per accelerare la spedizione del metodo. Eventuali suggerimenti?
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([email protected]))
}
)
setGeneric(
name = "create.foo2",
def = function(object) {standardGeneric("create.foo2")}
)
setMethod(
f = "create.foo2",
signature = "SpeedTest",
definition = function(object) {
z <- [email protected]
[email protected] <- 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 <- [email protected]; x <- [email protected]; for (i in seq(iters)) foo1(x)})
user system elapsed
1.47 0.00 1.46
> # retrieving [email protected] instead of x does not affect speed
> system.time({foo1 <- [email protected]; for (i in seq(iters)) foo1([email protected])})
user system elapsed
1.47 0.00 1.49
> # same speed as foo1 although no explicit argument
> system.time({foo2 <- [email protected]; 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
Grazie per l'utile suggerimento. La ragione per cui la mia rappresentazione e i miei metodi di dati non sono vettorializzati: sto usando il polimorfismo. Nel mio codice ho un metodo diverso.foo per sottoclasse e diverse persone potrebbero scrivere metodi diversi. Quindi, a differenza dell'esempio, ogni chiamata a method.foo chiama un metodo diverso e non so cosa sia nel corpo di ciascun metodo. – Soldalma