Georg Kindermann
2020-Nov-30 10:12 UTC
[R] Why is R making a copy-on-modification after using str?
Dear list members, I was wondering why R is making a copy-on-modification after using str. 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 I am using R version 4.0.3. Kind regards, Georg
Duncan Murdoch
2020-Nov-30 15:25 UTC
[R] Why is R making a copy-on-modification after using str?
On 30/11/2020 5:12 a.m., Georg Kindermann wrote:> Dear list members, > > I was wondering why R is making a copy-on-modification after using str.This isn't really an explanation, but adds a bit more data. If you inspect m before and after str(), you'll see that str(m) leaves it with two references: > m <- matrix(1:12, 3) > .Internal(inspect(m)) @7fcb0ad682c8 13 INTSXP g0c4 [REF(1),ATT] (len=12, tl=0) 1,2,3,4,5,... ATTRIB: @7fcaf5f7b8a0 02 LISTSXP g0c0 [REF(1)] TAG: @7fcafd091a80 01 SYMSXP g1c0 [MARK,REF(65535),LCK,gp=0x6000] "dim" (has value) @7fcb0afecc80 13 INTSXP g0c1 [REF(65535)] (len=2, tl=0) 3,4 > str(m) int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ... > .Internal(inspect(m)) @7fcb0ad682c8 13 INTSXP g0c4 [REF(2),ATT] (len=12, tl=0) 1,2,3,4,5,... ATTRIB: @7fcaf5f7b8a0 02 LISTSXP g0c0 [REF(1)] TAG: @7fcafd091a80 01 SYMSXP g1c0 [MARK,REF(65535),LCK,gp=0x6000] "dim" (has value) @7fcb0afecc80 13 INTSXP g0c1 [REF(65535)] (len=2, tl=0) 3,4 It's not just str(): this sequence also does it. m <- matrix(1:12, 3) debug(mean) mean(m) Hit c a couple of times now to get out of debugging, and m is left with two references to it. I don't see that if mean isn't being debugged. Duncan Murdoch> > 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 > > I am using R version 4.0.3. > > Kind regards, > Georg > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
iuke-tier@ey m@iii@g oii uiow@@edu
2020-Nov-30 18:30 UTC
[R] [External] Why is R making a copy-on-modification after using str?
On Mon, 30 Nov 2020, Georg Kindermann wrote:> Dear list members, > > I was wondering why R is making a copy-on-modification after using str. > > 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]: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.> 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 >This _may_ be related to references created in the process of protecting the return value from evaluation. If so, addressing the debug issue raised by Duncan may resolve this. If not, someone will have to take a closer look. Best, luke> I am using R version 4.0.3. > > Kind regards, > Georg > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Luke Tierney Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke-tierney at uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu