为什么as.vector深度复制矩阵?

为什么as.vector深度复制矩阵?,r,R,使用top,我在以下代码块注释中指定的特定点手动测量了以下内存使用情况: x <- matrix(rnorm(1e9),nrow=1e4) #~15gb gc() # ~7gb after gc() y <- as.vector(x) gc() #~15gb after gc() x你问的问题是推理。这似乎更适合R-devel,我假设作为回报的答案是“没人知道”。R源的相关功能是 在调用as.vector(矩阵(…)的源代码中,需要注意的是模式的默认参数是any。这就意味着。这让

使用
top
,我在以下代码块注释中指定的特定点手动测量了以下内存使用情况:

x <- matrix(rnorm(1e9),nrow=1e4) 
#~15gb
gc()
# ~7gb after gc()
y <- as.vector(x)
gc()
#~15gb after gc()

x你问的问题是推理。这似乎更适合R-devel,我假设作为回报的答案是“没人知道”。R源的相关功能是

在调用
as.vector(矩阵(…)
的源代码中,需要注意的是
模式的默认参数是
any
。这就意味着。这让我们能够找到复制行为的原因

// source reference: do_asvector
...
    if(type == ANYSXP || TYPEOF(x) == type) {
    switch(TYPEOF(x)) {
    case LGLSXP:
    case INTSXP:
    case REALSXP:
    case CPLXSXP:
    case STRSXP:
    case RAWSXP:
        if(ATTRIB(x) == R_NilValue) return x;
        ans  = MAYBE_REFERENCED(x) ? duplicate(x) : x; // <== evil culprit
        CLEAR_ATTRIB(ans);
        return ans;
    case EXPRSXP:
    case VECSXP:
        return x;
    default:
        ;
    }
...
因此,我们可以想象,在
do\u asvector
中调用
duplicate
可以被调用
shallow\u duplicate
代替。可能在最初实施代码时(根据中的注释,在R-2.13.0之前)选择了“比抱歉更安全”的策略,或者可能在
ascommon
未处理的类型中存在需要深度拷贝的场景

现在,如果我们设置
mode='list'
或在不赋值的情况下通过列表,我将测试函数是否执行深度复制。在任何一种情况下,向R-devel邮件列表发送后续问题都不是一个坏主意

编辑:
在最后的
gc()
中,您有
x
指向具有
dim
属性的向量,以及
y
指向没有任何
dim
属性的向量。数据是对象的固有部分,它不是属性,因此这两个向量必须不同

如果矩阵已作为列表实施,例如:

 x <- list(data = rnorm(1e9), dim = c(1e4, 1e5))

x@waldi,答案是……不完整的。的确,从用户的角度来看,对象是不可变的,但是R使用“修改时复制”优化来避免在必要时复制内存中的值。也就是说,对象可以是指向同一个值的指针,直到值发生分歧,然后才进行复制:看吧,我的问题是,当你可以想象矩阵被存储为指向某个元数据的指针(nrow、ncol和指向向量的指针)时,为什么R考虑向量和矩阵之间的强制是一种“修改”。我在问:R中的矩阵存储的哪些细节阻止了这里出现这种优化?感谢您的澄清相关:R中的torch具有零拷贝整形()不做与原子向量上的
duplicate
相同的事情?老实说,我不知道您问题的答案。但再一次,通过一些挖掘,
shallow\u duplicate
确实调用了
duplicate\u ATOMIC\u VECTOR
(参见:src/main/duplicate.c),它反过来执行完整的内存拷贝,但执行属性的浅拷贝(有趣的选择)。我可以想象,创建连续内存块所花费的时间将超过其他成本。所以我不确定我是否同意效率的理由。但是你是对的,在给定矩阵(原子向量)作为输入的特定情况下,使用shallow_dup不会有什么区别。它可能在其他地方出现。:-)
 x <- list(data = rnorm(1e9), dim = c(1e4, 1e5))