R包nlt/adlift/ebayesthresh使用大量内存; 如何提高性能?

8 memory parallel-processing optimization performance r

这一切都始于一个我需要严格使用的R包('nlt'),它有另外两个(非常大的)包依赖('adlift','ebayesthresh').我需要它来分析大约4000点的数据样本.

算法创建了许多"隐藏"向量,所以即使乍一看你认为你有足够的内存来加载数据样本并处理它,事情也会变得很快.在这一点上,我应该提到我有4GB内存的Ubuntu x64和Windows x64.

出于纯粹的好奇心和受虐狂,我猜,我决定尝试一下Amazon EC2实例.最后我想其中几个,我在停止高内存超大型实例 17.1 GB内存,6.5的ECU,再次的时候,我跑出来的内存和Ubuntu杀了我的运行功能.

我最终使用了split-apply-combine方法与'snowall','foreach''doSMP'.我调整了数据,处理了每个chunck并合并了结果.谢天谢地lapply和sfLapply存在.在我的笔记本电脑上在7分钟内分析样品.

我想我应该感到高兴,但是7分钟仍然很多,我不想再次向亚马逊EC2跳枪,除非没有其他的东西可以缩短运行时间.

我做了一些研究,R的'bigmemory''ff'软件包似乎允许相当大的加速,特别是如果我使用了文件备份数据.

所述"NLT"包只需要矢量作为输入,和"bigmemory"例如有其特殊的数据类型,则big.matrix.即使我神奇地能够将big.matrix提供给' nlt '包,这仍然会留下许多新的向量分配,其中标准的R函数被硬编码到包中并且依赖于它.

我一直在考虑面向方面的编程/猴子修补,我设法找到了这种东西的唯一R包,'r-connect'.

现在,正如我所看到的,我有两个主要选择:

  • 手动重写nlt包及其所有函数依赖关系来自其他2个包而不是标准的R list(),matrix()等,使用'bigmemory'函数,这是一个噩梦.
  • 'bigmemory'函数 替换标准R列表,矩阵等

我跳鲨鱼了吗?任何人都可以提出另一种解决方案或分享类似的经

Jos*_*ich 4

另一种选择是分析这 3 个包的内存使用情况并删除所有冗余数据并在不再需要时删除对象。

更新:
nlt不太复杂;它主要是包装adliftEbayesThresh功能,所以我会看一下这两个包。

以 adlift/R/Amatdual.R 为例:AdualHdual在函数开头初始化Amatdual,但它们从未在函数中索引;它们稍后会被完全重新创建。

Adual <- matrix(0, n - steps + 1, n - steps + 1)
Hdual <- matrix(0, n - steps, n - steps + 1)
...
    Hdual <- cbind(diag(length(newpoints) - 1), lastcol)
...
Adual <- rbind(Hdual, as.row(Gdual))
Run Code Online (Sandbox Code Playgroud)

不需要这两个初始分配。

adlift并且nlt还有多种用途apply,可以切换为行/列平均值/总和。我不确定这对内存使用有多大帮助,但它会更快。IE:

apply(foo, 1, sum)   # same as rowSums(foo)
apply(foo, 2, sum)   # same as colSums(foo)
apply(foo, 1, mean)  # same as rowMeans(foo)
apply(foo, 2, mean)  # same as colMeans(foo)
Run Code Online (Sandbox Code Playgroud)

  • @jakker:这里的问题是由对数学有深刻理解而对计算机科学有浅薄理解的人编写的代码——在计算科学中经常发生,无论使用哪种语言。 (5认同)
  • @jakker:确保在 rm() 之后运行 gc() 以释放内存。 (2认同)
  • 是的,我想我会尽可能多地挖掘和重写。我刚刚再次确认自己,由于内存分配方式,速度如此之慢。我进一步减小了分割-应用-组合的数据块的大小,并且我的运行时间几乎减少了一半。该死的R!!再次感谢您的建议! (2认同)
  • @Joshua Ulrich:他已经收到通知,我希望他也很高兴它不再耗尽内存。据我所知,这是继承的代码,而不是他从头开始编写的,所以这是可以理解的。在那里度过愉快的一天! (2认同)