내 S4 클래스에는 여러 번 호출되는 메서드가 있습니다. 비슷한 함수가 독립적으로 호출 된 경우보다 실행 시간이 훨씬 느리다는 것을 알게되었습니다. 그래서 "function"타입의 슬롯을 클래스에 추가하고 메소드 대신이 함수를 사용했습니다. 아래 예제는이 작업을 수행하는 두 가지 방법을 보여 주며 둘 다 해당 메서드보다 훨씬 빠르게 실행됩니다. 또한이 예제는 메서드의 속도가 느리다고해서 메서드가 클래스에서 데이터를 검색해야하기 때문에 함수가 더 빠르기 때문에 메서드가 더 빠르다고 제안합니다.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([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
유용한 제안을 보내 주셔서 감사합니다. 내 데이터 표현 및 메서드가 벡터화되지 않은 이유 : 다형성을 사용하고 있습니다. 내 코드에는 하위 메서드마다 다른 메서드가 있습니다. 다른 사람들은 다른 메서드를 작성할 수 있습니다. 그래서 예제와 다르게, method.foo에 대한 각각의 호출은 다른 메소드를 호출하고, 각 메소드의 본문에 무엇이 있는지를 알지 못합니다. – Soldalma