我想知道为什么 R 在使用str
.
我创建一个matrix
. 我可以改变它dim
,一个元素甚至全部。没有复制。但是当str
在 Matrix 上的下一个修改操作期间调用R 正在制作副本时。为什么会这样?
m <- matrix(1:12, 3)
tracemem(m)
#[1] "<0x559df861af28>"
dim(m) <- 4:3
m[1,1] <- 0L
m[] <- 12:1
str(m)
# int [1:4, 1:3] 12 11 10 9 8 7 6 5 4 3 ...
dim(m) <- 3:4 #Here after str a copy is made
#tracemem[0x559df861af28 -> 0x559df838e4a8]:
dim(m) <- 3:4
str(m)
# int [1:3, 1:4] 12 11 10 9 8 7 6 5 4 3 ...
dim(m) <- 3:4 #Here again after str a copy
#tracemem[0x559df838e4a8 -> 0x559df82c9d78]:
Run Code Online (Sandbox Code Playgroud)
我也想知道为什么在有任务回调时会复制一份。
TCB <- addTaskCallback(function(...) TRUE)
m <- matrix(1:12, nrow = 3)
tracemem(m)
#[1] "<0x559dfa79def8>"
dim(m) <- 4:3 #Copy on modification
#tracemem[0x559dfa79def8 -> 0x559dfa8998e8]:
removeTaskCallback(TCB)
#[1] TRUE
dim(m) <- 4:3 #No copy
Run Code Online (Sandbox Code Playgroud)
会话信息()
R version 4.0.3 (2020-10-10)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Debian GNU/Linux 10 (buster)
Matrix products: default
BLAS: /usr/local/lib/R/lib/libRblas.so
LAPACK: /usr/local/lib/R/lib/libRlapack.so
locale:
[1] LC_CTYPE=de_AT.UTF-8 LC_NUMERIC=C
[3] LC_TIME=de_AT.UTF-8 LC_COLLATE=de_AT.UTF-8
[5] LC_MONETARY=de_AT.UTF-8 LC_MESSAGES=de_AT.UTF-8
[7] LC_PAPER=de_AT.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=de_AT.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.0.3
Run Code Online (Sandbox Code Playgroud)
这是修改属性时是否有办法防止修改时复制的后续问题?.
我开始 RR --vanilla
有一个干净的会话。
我已经按照@sam-mason 在评论中的建议在R-help上问了这个问题。
Luke Tierney 的回答解决了这个问题str
:
从 R 4.0.0 开始,在某些情况下可以在内部减少引用计数,因此在这种情况下避免复制。尝试检测可以删除计数的所有情况的成本太高了,但在这种情况下我们可以做得更好。事实证明,pos.to.env 的内部结构不必要地创建了对调用环境的额外引用(此处是对exists() 的调用)。这已在 r79528 中修复。谢谢。
并与Task Callback
:
事实证明,处理回调调用的方式存在一些问题。这已在 R-devel 中的 r79541 中进行了修订。这个例子将不再需要在 R-devel 中重复。
谢谢你的报告。