2009-09-10 136 views

回答

9
  • 使用多个内核/机器应该是简单的,如果你仅仅使用平行独立的重复,但要注意随机数生成器的常见缺陷(例如,如果使用当前时间作为种子,产卵许多过程一个RNG每个可能会产生相关的随机数,从而导致无效的结果 - 例如见this paper

  • 您可能需要使用variance reduction减少所需的复制,即数量缩小所需样本的大小。更多先进的方差减少技术可以在许多教科书中找到,例如,在this one

3

拉丁超立方体采样很容易应用,对结果有很大影响。基本上,您可以从统一分布中获取拉丁超立方体样本(例如,在包中使用randomLHS()),并使用例如qnorm(uniformsample)将其转换为您所需的分布。

5

Preallocate your vectors!

> nsims <- 10000 
> n <- 100 
> 
> system.time({ 
    res <- NULL 
    for (i in 1:nsims) { 
     res <- c(res,mean(rnorm(n))) 
    } 
}) 
    user system elapsed 
    0.761 0.015 0.783 
> 
> system.time({ 
    res <- rep(NA, nsims) 
    for (i in 1:nsims) { 
     res[i] <- mean(rnorm(n)) 
    } 
}) 
    user system elapsed 
    0.485 0.001 0.488 
> 
+0

我在模型中使用这只是昨天它将我的运行时间缩短了15%以上。当然值得一行代码。 – 2009-09-11 15:23:53

+0

这是一个伟大的小窍门 – Dan 2009-09-11 17:43:28

3

我知道这个线程是真的老了,但如果有人绊倒,并正在寻找更快的方法,我认为以下工作:

library(data.table) 
library(microbenchmark) 

nsims <- 10000 
n <- 100 

# Answer from @Eduardo_Leoni: 
preallocate<-function(nsims, n) { 
    res <- rep(NA, nsims) 
    for (i in 1:nsims) { 
    res[i] <- mean(rnorm(n)) 
    } 
    return(res) 
} 

# Answer using data.table: 
datatable<-function(nsims,n) { 
    dt <- data.table(i=1:nsims)[,list(res=mean(rnorm(1:n))),by=i] 
    return(dt) 
} 

# Timing benchmark: 
microbenchmark(preallocate(nsims,n), datatable(nsims,n), times=100) 
#Unit: milliseconds 
#     expr  min  lq median  uq  max neval 
# preallocate(nsims, n) 428.4022 432.3249 434.2910 436.4806 489.2061 100 
# datatable(nsims, n) 238.9006 242.3517 244.1229 246.5998 303.6133 100 
+1

你应该在同一台计算机上运行你的解决方案和其他人(因为一些计算机比其他计算机更快)。我发现你比'microbenchmark'的循环慢了一点;和'replicate(nsims,mean(rnorm(1:n)))'稍快一点。这在两种情况下都有3%的差异。 – Frank 2013-09-02 14:01:08

+1

感谢您的建议,@Frank,并看到编辑的答案。在我的系统上,'data.table'使得@Eduardo_Leoni的循环解决方案的速度提高了〜1.8倍。请让我知道,如果我失去了一些东西,因为我绝对不是基准测试的细微差别的专家...... – dnlbrky 2013-09-07 12:43:57

+0

非常有帮助。使用这个技巧,我将计算时间从250秒减少到了60秒。 – 2014-08-04 03:20:28