我的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,不同的人可能會編寫不同的方法。因此,與示例不同,每次調用method.foo都調用不同的方法,我不知道每個方法的內容是什麼。 – Soldalma 2013-05-06 15:06:20