Ale*_*lex 18 copy r reference deep-copy data.table
我想了解R在将参数传递给函数,创建变量副本等时使用的逻辑与内存使用情况有关.它什么时候实际创建变量的副本而不是仅仅传递对该变量的引用?特别是我很好奇的情况是:
f <- function(x) {x+1}
a <- 1
f(a)
Run Code Online (Sandbox Code Playgroud)
是a字面意思传递还是被传递的参考?
x <- 1
y <- x
Run Code Online (Sandbox Code Playgroud)
复制参考?什么时候不是这样的?
如果有人能向我解释这一点,我将非常感谢.
42-*_*42- 15
当它传递变量时,它总是通过复制而不是通过引用.但是,有时候,在实际发生任务之前,您不会获得副本.该过程的真实描述是传承承诺.看一下文档
?force
?delayedAssign
Run Code Online (Sandbox Code Playgroud)
一个实际意义是,即使不是不可能,也很难避免需要至少两倍于名义上占据的对象的RAM.修改大对象通常需要制作临时副本.
更新:2015:我确实(并且确实)同意Matt Dowle的观点,他的data.table包提供了一种替代的分配路径,可以避免复制 - 重复问题.如果那是请求的更新,那么我在提出建议时并不理解.
有在评价规则中的R 3.2.1最近的变化apply和Reduce.这是在SO-宣布参考这里的新闻:从lapply返回匿名函数 - 出了什么问题?
迟到的答案,但语言设计的一个非常重要的方面在网络上没有得到足够的报道(或至少是通常的来源)。
x <- c(0,4,2)
lobstr::obj_addr(x)
# [1] "0x7ff25e82b0f8"
y <- x
lobstr::obj_addr(y)
# [1] "0x7ff25e82b0f8"
Run Code Online (Sandbox Code Playgroud)
注意相同的“内存地址”,即对象在内存中的存储位置。由此可以确认x,并y都指向相同的标识符。
Hadley Wickham 的 Advanced R 书对此进行了介绍:
考虑这个代码:
x <- c(1, 2, 3)很容易理解为:“创建一个名为 'x' 的对象,包含值 1、2 和 3”。不幸的是,这种简化会导致对 R 在幕后实际所做的事情的预测不准确。更准确地说,这段代码做了两件事:
它正在创建一个对象,一个值向量,
c(1, 2, 3)。它将该对象绑定到一个名称,x. 换句话说,对象或值没有名称;它实际上是具有价值的名称。
请注意,它们的内存地址是短暂的,并且会随着每个新的 R 会话而变化。
现在是重要的部分。
在 R 语义中,对象是按值复制的。这意味着修改副本会使原始对象保持完整。由于在内存中复制数据是一项昂贵的操作,因此 R 中的副本尽可能地懒惰。它们仅在实际修改新对象时发生。来源:[R lang 文档][1]
所以如果我们现在y通过向向量附加一个值来修改 的值,y现在指向一个不同的“对象”。这与文档所说的关于“仅在修改新对象时”(懒惰)发生的复制操作一致。y指向与以前不同的地址。
y <- c(y, -3)
print(lobstr::obj_addr(y))
# [1] "0x7ff25e825b48"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8991 次 |
| 最近记录: |