【发布时间】:2019-07-02 00:57:28
【问题描述】:
我有一个 rollapply 函数,它做一些非常简单的事情,但是超过百万个数据点,这个简单的函数非常慢。我想知道是否可以提供信息来 rollapply 以了解如何进行下一次转换,而不是定义函数本身。
具体来说,我正在为基本的统计异常检测执行滚动窗口。
滚动应用功能:
minmax <- function(x) { max(x) - min(x) }
调用者:
mclapply(data[,eval(vars),with=F],
function(x) rollapply(x,width=winSize,FUN=minmax,fill=NA),
mc.cores=8)
data 是 8 列 data.table,winsize 是 300
此调用在 8 个内核上大约需要 2 分钟。它是整体计算的主要瓶颈之一。但是我可以想象我们可以保持它们排序(按值和索引),然后在每次滑动时进行 Olog(n) 比较。
但是,我经常看到建议不要使用 for 循环并使用 lapply 的帖子。进一步优化的下一个合乎逻辑的步骤是什么?
【问题讨论】:
-
如果您所指的帖子(建议
lapply循环使用)已有几年历史,那么他们可能会说因为for循环使用速度较慢。这已被修复(R-3.0?),因此for循环总是较慢的前提可能是不明智的。有时不 使用for循环更有意义(当您不想要副作用并且想要捕获循环中每次迭代的结果时),在这种情况下*apply函数之一可能更有意义。 -
当使用像
mclapply这样的并行函数时,我最关心的是内核之间传递了多少数据。例如,如果你从mc.cores=8转到(比如说)=4,你的执行时间会加倍吗?=12(如果你有更多)呢?如果您没有看到使用更多内核明显提高性能,您可能会因为复制数据而遇到延迟(取决于您的并行设置)。因此,也许加快速度不仅仅与您的 UDF 相关(它的效率与原始形式一样高)。 -
由于我是 r 新手,所以我不知道 for 循环中的性能变化。我将看到一个 for 循环排序窗口如何执行 w.r.t。滚动应用。有意识地选择了 8 个核心,因为有 8 个 rollapplies(和 8 个核心)。我打算换一台 36 核的新机器,也许我可以研究阿姆达尔定律的影响。在我弄清楚远程 r in ess 之后。感谢您的建议
-
ESS 中的远程 R:取决于您的需要。对我来说,我在远程系统上安装了 emacs/ess,所以
ssh和tmux(screen) 就足够了;当我需要查看绘图时,我使用rmote。我读过ESS-Remote,但从未尝试过。
标签: r optimization rollapply