18

目前我正在处理相对较大的数据文件,并且我的计算机不是超级计算机。我正在临时创建这些数据集的许多子集,并且不会将它们从工作区中删除。显然,这些因素使许多变量变得混乱。但是,有许多未使用的变量对 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)

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

4

4 回答 4

20

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

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

解决这些问题的一种方法是广泛使用local. 当您进行分散在许多临时对象周围的计算时,您可以将其包装在local调用中,这将在之后有效地为您处理这些对象。不再需要清理大量的i, j, x,temp.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(...)
})
于 2013-06-20T16:39:08.000 回答
4

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

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

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

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

于 2014-05-05T09:07:44.023 回答
1

我认为无论语言如何,删除未使用的代码都是一种很好的编程习惯。

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

这是专业编码的基础。

于 2013-06-20T16:11:06.853 回答
1

根据@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
}
于 2018-06-24T15:37:09.913 回答