gpt4 book ai didi

R 无故复制

转载 作者:行者123 更新时间:2023-12-04 16:06:00 26 4
gpt4 key购买 nike

一些 R 函数会让 R 在函数调用后复制对象,如 nrow,而另一些则不会,如 sum。
例如下面的代码:

x = as.double(1:1e8)
system.time(x[1] <- 100)
y = sum(x)
system.time(x[1] <- 200) ## Fast (takes 0s), after calling sum
foo = function(x) {
return(sum(x))
}
y = foo(x)
system.time(x[1] <- 300) ## Slow (takes 0.35s), after calling foo

调用 foo 并不慢,因为 x 没有被复制。但是,再次更改 x 非常慢,因为 x 被复制。我的猜测是调用 foo 会留下对 x 的引用,因此在更改它之后,R 会制作另一个副本。

有谁知道为什么 R 这样做?即使函数根本不改变 x ?谢谢。

最佳答案

我绝对推荐哈德利的 Advanced R本书,因为它深入研究了您可能会发现有趣和相关的一些内部结构。与您的问题最相关(正如@joran 和@lmo 所提到的),速度变慢的原因是强制复制修改的附加引用。

可能对 Memory#Modification 有益的摘录:

There are two possibilities:

  • R modifies x in place.

  • R makes a copy of x to a new location, modifies the copy, and then uses the name x to point to the new location.

It turns out that R can do either depending on the circumstances. In the example above, it will modify in place. But if another variable also points to x, then R will copy it to a new location. To explore what’s going on in greater detail, we use two tools from the pryr package. Given the name of a variable, address() will tell us the variable’s location in memory and refs() will tell us how many names point to that location.



同样感兴趣的是 R's C interface 上的部分和 Performance . pryr 包还具有以更简单的方式处理这些内部结构的工具。

Hadley 的书(相同的内存部分)中的最后一个注释可能会有所帮助:

While determining that copies are being made is not hard, preventing such behaviour is. If you find yourself resorting to exotic tricks to avoid copies, it may be time to rewrite your function in C++, as described in Rcpp.

关于R 无故复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42559356/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com