【问题标题】:Should I get a habit of removing unused variables in R?我应该养成删除 R 中未使用的变量的习惯吗?
【发布时间】:2013-06-20 16:00:36
【问题描述】:

目前我正在处理相对较大的数据文件,并且我的计算机不是超级计算机。我正在临时创建这些数据集的许多子集,并且不会将它们从工作区中删除。显然,这些因素使许多变量变得混乱。但是,有许多未使用的变量对 R 的性能有什么影响吗? (即计算机的内存是否会在某个时候填满?)
在编写代码时,我应该养成删除未使用变量的习惯吗?值得吗?

x <- rnorm(1e8)
y <- mean(x)
# After this point I will not use x anymore, but I will use y
# Should I add following line to my code? or 
#   Maybe there will not be any performance lag if I skip the following line:
rm(x)

我不想在我的代码中添加另一行。与其让我的代码看起来杂乱无章,我更喜欢我的工作区杂乱无章(如果没有性能改进的话)。

【问题讨论】:

  • 也可以使用gc()函数让R进行垃圾回收。我发现这在删除大对象后很有用,因为 R 在删除对象后似乎不会立即恢复内存。
  • 最小化中间对象的创建也不错。显然,在您的示例中,您可以直接转到y &lt;- mean(rnorm(1e8))。我发现magrittr 的管道非常有助于组合我以前保存到临时变量的步骤。

标签: performance r variables memory


【解决方案1】:

是的,有未使用的对象会影响你的性能,因为 R 将它的所有对象都存储在内存中。显然,小对象的影响可以忽略不计,您通常只需要删除真正大的对象(具有数百万行的数据框等),但拥有整洁的工作空间不会有任何伤害。

唯一的风险是删除您以后需要的东西。即使按照建议使用存储库,您也希望避免意外破坏内容。

解决这些问题的一种方法是广泛使用local。当您进行分散在许多临时对象周围的计算时,您可以将其包装在 local 调用中,这将在之后有效地为您处理这些对象。不再需要清理大量的ijxtemp.var 等等。

local({
    x <- something
    for(i in seq_along(obj))
        temp <- some_unvectorised function(obj[[i]], x)
        for(j in 1:temp)
            temp2 <- some_other_unvectorised_function(temp, j)
    # x, i, j, temp, temp2 only exist for the duration of local(...)
})

【讨论】:

  • @Hong Ooi,问题发起者如何使用这个?如果将 y 和 x 放在 local 调用中,它们不会同时存在吗?
【解决方案2】:

除了以上建议,为了帮助像我这样的初学者,我想列出检查 R 内存的步骤:

  1. 使用ls()列出未使用的对象。
  2. 使用object.size("Object_name")检查感兴趣的对象
  3. 使用rm("Object_name") 删除未使用/不必要的对象
  4. 使用gc()
  5. 检查使用memory.size()清除的内存

如果您使用的是新会话,请使用rm(list=ls()),后跟gc()

如果有人觉得删除未使用变量的习惯可能很危险,那么偶尔将对象保存到 R 图像中总是一种好习惯。

【讨论】:

  • 列出对象大小:size
【解决方案3】:

我认为删除未使用的代码是一种很好的编程习惯,不管是什么语言。

使用像 Subversion 或 Git 这样的版本控制系统来跟踪您的更改历史记录也是一个很好的做法。如果你这样做了,你可以毫无顾忌地删除代码,因为如果你需要,总是可以回滚到早期版本。

这是专业编码的基础。

【讨论】:

  • OP 的问题是关于未使用变量的性能拖累,而不是未使用的代码。
  • @duffymo 感谢您的回复。我想我的问题不是很清楚。我编辑了我的问题。
  • 我明白“我应该养成删除 R 中未使用的变量的习惯吗?”方法。我的观点是应该这样做,但不是因为性能拖累。
【解决方案4】:

根据@Peter Raynham 显示最大对象的分布并返回它们的名称:

memory.biggest.objects <- function(n=10) { # Show distribution of the largest objects and return their names
  Sizes.of.objects.in.mem <- sapply( ls( envir = .GlobalEnv), FUN = function(name) { object.size(get(name)) } );
  topX= sort(Sizes.of.objects.in.mem,decreasing=T)[1:n]

  Memorty.usage.stat =c(topX, 'Other' = sum(sort(Sizes.of.objects.in.mem,decreasing=T)[-(1:n)]))
  pie(Memorty.usage.stat, cex=.5, sub=make.names(date()))
  # wpie(Memorty.usage.stat, cex=.5 )
  # Use wpie if you have MarkdownReports, from https://github.com/vertesy/MarkdownReports
  print(topX)
  print("rm(list=c( 'objectA',  'objectB'))")
  # inline_vec.char(names(topX))
  # Use inline_vec.char if you have DataInCode, from https://github.com/vertesy/DataInCode
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多