gpt4 book ai didi

r - R 是否在分配时复制 S4 类(class)中未评估的插槽?

转载 作者:行者123 更新时间:2023-12-04 18:07:50 25 4
gpt4 key购买 nike

假设我有一个带有两个插槽的 S4 类。然后我创建一个方法,将其中一个插槽设置为某物并返回结果。另一个插槽也会在分配时复制吗?

例如,

setClass('foo', representation(first.slot = 'numeric', second.slot = 'numeric'))
setGeneric('setFirstSlot', function(object, value) {standardGeneric('setFirstSlot')})
setMethod('setFirstSlot', signature('foo', 'numeric'), function(object, value) {
object@first.slot = value
return(object)
})

f <- new('foo')
f@second.slot <- 2
f <- setFirstSlot(f, 1)

在最后一行,第一个和第二个插槽的值会被复制还是会进行某种优化?我有一个类,其中一个字段包含 1 GB 的数据,几个字段带有小数值向量,我想为数值字段设置一个 setter 函数,这样每次使用时都不会浪费时间不必要地复制数据。

谢谢 :)

最佳答案

如果要复制字段中的大量数据,一种解决方案是使用引用类。让我们将引用类与 S4 进行比较。

## Store timing output
m = matrix(0, ncol=4, nrow=6)

创建函数类定义:
foo_ref = setRefClass("test", fields = list(x = "numeric", y = "numeric"))

然后时间数据分配:
## Reference class
g = function(x) {x$x[1] = 1; return(x)}
for(i in 6:8){
f = foo_ref$new(x = 1, y = 1)
y = runif(10^i)
t1 = system.time({f$y <- y})[3]
t2 = system.time({f$y[1] = 1})[3]
t3 = system.time({f$x = 1})[3]
t4 = system.time({g(f)})[3]
m[i-5, ] = c(t1, t2, t3, t4)
}

我们可以重复类似的 S4 结构:
g = function(x) {x@y[1] = 1; return(x)}
setClass('foo_s4', representation(x = 'numeric', y = 'numeric'))
for(i in 6:8){
f = new('foo_s4'); f@x = 1; f@y = 1
y = runif(10^i)
t1 = system.time({f@y <- y})[3]
t2 = system.time({f@y[1] <- 1})[3]
t3 = system.time({f@x = 1})[3]
t4 = system.time({g(f)})[3]
m[i-2, ] = c(t1, t2, t3, t4)
}

结果

在处理函数时,对大型数据集使用引用类结构的赋值要高效得多。

enter image description here

笔记
  • R 版本 3.1 的结果
  • 对于 R < 3.1,t3 S4 对象的时间更高。
  • 关于r - R 是否在分配时复制 S4 类(class)中未评估的插槽?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22448198/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com