在R中,在循环之前初始化列表的最节省内存的方法是什么?



我想知道初始化列表的最有效的内存方式是在R中,如果该列表将在循环中用于存储结果。我知道在循环中增长对象会严重影响计算效率,所以我尽量避免这种情况。

我的问题如下。我有几组数据,我想单独处理。我的代码的要点是,我有一个循环,每次运行一个组,进行一些t测试,然后只返回统计上显著的结果(因此每个组的结果长度可变)。到目前为止,我正在初始化一个length(groups)列表来存储每次迭代的结果。

我的主要问题是我应该如何初始化列表,使对象不会在循环中增长。

  • 初始化list = vector(mode = "list", length=length(groups))是否足够好?
    • 我对此持怀疑态度,因为它只是创建了一个length(groups)列表,但每个条目都等于NULL。我担心的是,在循环的每次迭代中,当我将数据存储到列表中时,每次当条目从NULL到我的结果向量时,它都会重新复制对象,在这种情况下,初始化列表并没有多大好处。我不知道list的内部是如何工作的,但是,所以它有可能只是存储对存储在列表中的矢量的引用,这意味着不需要重新复制。
  • 另一种方法是将list中的每个元素初始化为结果可能具有的最大长度的vector。
    • 这不是一个大问题,因为可能有效结果的最大数量是已知的。如果我采用这种方法,我会用循环中的结果向量覆盖每个向量。由于已经预留了最大内存量,希望不会发生重复制/增长。但是,如果没有必要,并且上面的第一个选项足够好,我不想采用这种方法。

下面是一些描述我的问题的伪代码

#initialize variables
results = vector(mode="list", length=length(groups)) #the line of code in question
y=1
tTests = vector(length = length(singleGroup))    
#perform analysis on each group in groups
for(group in groups)
{
  #returns a vector of p values with one entry per element in group
  tTests = tTestFunction(group) 
  results[[y]] = tTests<=0.05
  y=y+1
}   

你的代码不工作,所以它是一个坏的例子。想想看:

x <- vector("list", length = 4)
tracemem(x)  ## trace memory copies of "x"
for (i in 1:4) x[[i]] <- rnorm(4)

在更新期间没有额外的x副本。所以没什么好担心的。

正如@lmo所建议的,即使您使用x <- list()来初始化这个列表,也不会产生内存复制。


我的回答的目的,是指你使用tracemem,当你想要跟踪(可能的)内存副本在代码执行期间。如果你知道这个功能,你就不会来找我们了。

这是我的另一个答案,与使用tracemem有关。不过,这是在一个不同的背景下。在这里,您可以看到创建内存副本时tracemem将返回什么。

相关内容

  • 没有找到相关文章

最新更新