gpt4 book ai didi

r - R 中的惰性求值 – 分配是否受影响?

转载 作者:行者123 更新时间:2023-12-03 11:59:32 24 4
gpt4 key购买 nike

我读了this basic question关于重命名对象和@Shane 的回答,指出我懒惰的评估。现在我想知道 assign也懒惰地评价。就像这里:

assign("someNewName",someOldObject)
rm(someOldObject)

我对此感到疑惑的原因是以下用例:假设我有 10K+ R 个对象,每个对象都有两个名为 originalName 的属性和 additionalName .现在我想编写一个函数,可以有效地让用户从一个名称切换到另一个名称,而不会丢失这两个属性。大概是这样...

编辑:根据@Hadley 的输入,我更改了我的代码。
switchObjectName <- function(x) {
n1 <- attributes(x)$originalName
n2 <- attributes(x)$additionalName
objName <- deparse(substitute(x))
if(objName == n1) {
delayedAssign(n2,x,assign.env=.GlobalEnv)
} else {
delayedAssign(n1,x,assign.env=.GlobalEnv)
}
rm(list=c(objName),envir=.GlobalEnv)
}

这很好用,但我很难获得 rm声明对。我试过 rm(objName,envir=.GlobalEnv)但无法让它工作,尽管 objName 绝对是一个字符,因为它是 deparse(substitute(x) 的结果.

最佳答案

R 语言通常具有值语义。作业x <- y表示 xy将是同一对象的独立副本(yx 上的更新将是独立的)。 x <- y 的简单实现将始终为 x 分配内存并完整复制y进去。相反,GNU-R 使用写时复制机制,它会将复制推迟到实际发生更新,这样可以节省内存/执行时间,以防万一它没有发生。 R 用户不必知道这种优化,它是完全透明的(除了一些罕见的情况,如内存不足错误)。此机制适用于写为 x <- y 的赋值。和 assign("x", y)相等。

惰性求值是语言设计的一部分,对 R 用户/程序员可见。作为参数传递给函数的表达式,例如在 foo(ls())传递的表达式是 ls() , 仅在被调用函数的实现需要时才进行惰性求值。
delayedAssign是一个低级函数,对 R 用户/程序员可见,但它实际上仅用于包的延迟加载,不应在用户程序中使用。 delayedAssign允许指定一个表达式来计算变量的值;仅当/当第一次读取变量时,计算才会延迟发生。

因此,要回答这个问题,R 中的赋值总是“惰性”的,因为它使用了写时复制机制。赋值右侧的计算也可以是惰性的(使用 delayedAssign ),但用户程序不应该需要/使用它。

我认为对于变量的“重命名”,没有必要使用 delayedAssign (因为不计算右侧)。它只会使情况更加复杂,并且由于簿记delayedAssign 可能会产生性能开销。必须要做。如果我必须重命名变量,我只会使用普通赋值。

为了代码清晰,我也会尽可能避免从环境中删除变量,甚至从函数分配到全局环境中,例如我只需创建一个新列表并将新的绑定(bind)(变量)插入其中。

提到了写时复制机制,在 GNU-R 中的当前实现中,任何所描述的解决方案都可能导致内存复制,如果没有重命名变量,这将是不必要的。在 R 级别无法避免这种情况。

关于r - R 中的惰性求值 – 分配是否受影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14884343/

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