Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is R making a copy-on-modification after using str?

Tags:

r

I was wondering why R is making a copy-on-modification after using str.

I create a matrix. I can change its dim, one element or even all. No copy is made. But when a call str R is making a copy during the next modification operation on the Matrix. Why is this happening?

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]:

Also I was wondering why a copy is made when having a Task Callback.

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

sessionInfo()

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

This is a follow up question to Is there a way to prevent copy-on-modify when modifying attributes?.

I start R with R --vanilla to have a clean session.

like image 449
GKi Avatar asked Nov 10 '20 08:11

GKi


1 Answers

I have asked this question on R-help as suggested by @sam-mason in the comments.

The answer from Luke Tierney solved the issue with str:

As of R 4.0.0 it is in some cases possible to reduce reference counts internally and so avoid a copy in cases like this. It would be too costly to try to detect all cases where a count can be dropped, but it this case we can do better. It turns out that the internals of pos.to.env were unnecessarily creating an extra reference to the call environment (here in a call to exists()). This is fixed in r79528. Thanks.

And related to Task Callback:

It turns out there were some issues with the way calls to the callbacks were handled. This has been revised in R-devel in r79541. This example will no longere need to duplicate in R-devel.

Thanks for the report.

like image 190
GKi Avatar answered Nov 08 '22 05:11

GKi