R中的不可变对象-引擎盖下发生了什么?

时间:2019-04-26 17:51:08

标签: r immutability

我有点困惑。我学会了永远不要增长向量,因为我们不想每次都创建一个对象的新副本。

# Bad
start <- Sys.time()

vector1 <- vector()

for(i in 1:100000000) {
  vector1[i] <- i
}

end <- Sys.time()

print(end - start)
Time difference of 17.06454 secs  



# Good
vector2 <- vector(length = 100000000)

start <- Sys.time()

for(i in 1:100000000) {
  vector2[i] <- i
}

end <- Sys.time()

print(end - start)
Time difference of 4.50159 secs

结果倾向于证明这一点是正确的,但是,例如,我在这里阅读:http://adv-r.had.co.nz/Functional-programming.html像这样:“可变状态通常很难,因为每次看起来就像在修改对象时,实际创建然后修改副本。”

那么我是否在示例2中每次在向量中存储新值时都不创建副本?因为每次迭代都会复制一个大小为100.000.000的向量,所以这样做是否通常不会更慢?

在这里我不明白什么?

1 个答案:

答案 0 :(得分:2)

您正在阅读的部分是在函数的上下文中。如果您检出the section on memory,将会看到

  

以下代码中的x会发生什么?

x <- 1:10
x[5] <- 10
     

有两种可能性:

     
      
  1. R修改x。

  2.   
  3. R将x的副本复制到新位置,修改副本,然后使用名称x指向新位置。

  4.   
     

事实证明,R可以视情况而定。在上面的示例中,它将进行修改。

因此,对于您正在做的事情,您需要进行适当的修改。您将不会针对以下内容进行修改:

f <- function(vec) {

    for(i in 1:length(vec)) {
        vec[i] <- i
    }

    return(vec)
}

在就地修改副本之前,您将创建vec的本地(对函数)副本。这就是哈德利的名言。