为什么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))