作为一个玩具例子,假设我们有一个名为“my_func”的函数(代码如下),它需要两个参数“n”和“p”。“my_func”将生成一个具有“n”行和“p”列的随机矩阵“x”,并在运行时和内存使用方面执行一些昂贵的操作,比如计算“x”的奇异值之和。(当然,该函数只有一行,但我在这里追求可读性。)
注意,对于大的 'n' 和 'p'(例如尝试 n = 1000 和 p = 2000),每次调用'my_func'都可能非常缓慢。
现在,在我的实际应用程序中,使用类似构造的函数时,'grid'中的行数比此处给出的要多得多。因此,我正在尝试更好地了解R中的向量化。
第一个问题:在上面的示例中,是否按顺序执行对'my_func'的调用,以便在下一次调用之前回收垃圾内存?我经常使用向量化,但从未停下来问这个问题。
第二个问题:(这个问题可能取决于第一个问题)假设调用次数足够多,并且'my_func'足够慢,这里是否需要并行处理?我假设是的。我的真正问题是:如果'my_func'改为为每次调用传递相同的大矩阵会怎样?为了论证,假设矩阵名为'y',有1000行和5000列,并且是即时计算的。当然,将矩阵'y'传递到每个并行节点将会产生一些滞后。
我理解第二个问题的答案可能是“取决于...”如果是这种情况,请告诉我,我将尝试提供更多细节。
此外,我感激任何建议、反馈或OMFG WTF N00B YOU HAVEN'T SEEN THIS OTHER OBSCURE SOMEWHAT RELEVANT DISCUSSION??!!!111oneone1
my_func <- function(n, p) {
x <- replicate(p, rnorm(n))
sum(svd(x)$d)
}
如果我们希望对“my_func”的几个值进行计算,并且对于每个“n”的值,我们有几个“p”的值,则将函数向量化,然后将其应用于组合到“my_func”是很简单的:
n <- 10 * seq_len(5)
p <- 100 * seq_len(10)
grid <- expand.grid(n = n, p = p)
my_func <- Vectorize(my_func)
set.seed(42)
do.call(my_func, grid)
[1] 98.61785 195.50822 292.21575 376.79186 468.13570 145.18359
[7] 280.67456 421.03196 557.87138 687.75040 168.42994 340.42452
[13] 509.65528 683.69883 851.29063 199.08474 400.25584 595.18311
[19] 784.21508 982.34591 220.73215 448.23698 669.02622 895.34184
[25] 1105.48817 242.52422 487.56694 735.67588 976.93840 1203.25949
注意,对于大的 'n' 和 'p'(例如尝试 n = 1000 和 p = 2000),每次调用'my_func'都可能非常缓慢。
现在,在我的实际应用程序中,使用类似构造的函数时,'grid'中的行数比此处给出的要多得多。因此,我正在尝试更好地了解R中的向量化。
第一个问题:在上面的示例中,是否按顺序执行对'my_func'的调用,以便在下一次调用之前回收垃圾内存?我经常使用向量化,但从未停下来问这个问题。
第二个问题:(这个问题可能取决于第一个问题)假设调用次数足够多,并且'my_func'足够慢,这里是否需要并行处理?我假设是的。我的真正问题是:如果'my_func'改为为每次调用传递相同的大矩阵会怎样?为了论证,假设矩阵名为'y',有1000行和5000列,并且是即时计算的。当然,将矩阵'y'传递到每个并行节点将会产生一些滞后。
我理解第二个问题的答案可能是“取决于...”如果是这种情况,请告诉我,我将尝试提供更多细节。
此外,我感激任何建议、反馈或OMFG WTF N00B YOU HAVEN'T SEEN THIS OTHER OBSCURE SOMEWHAT RELEVANT DISCUSSION??!!!111oneone1