为什么R循环比使用foreach慢10倍? [英] Why is R for loop 10 times slower than when using foreach?

查看:112
本文介绍了为什么R循环比使用foreach慢10倍?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这真的让我很难过我的计算机上的基本循环需要8秒钟:

  system.time({
x < - 0 $ b (1:2中的p){
(1:500中的i){
(1:5000中的j)){
x< -x + i * j



$)
x

如果我在非并行模式下使用 foreach ,它只需要0.7秒!!!

<$系统时间({
x< - 0
foreach(p = 1:2,.combine = rbind)%do%
for(i在1:500中){
(1:5000中的j){
x< -x + i * j
}
}
})
x

结果相同,但是 foreach 以某种方式能够达到它比基本的R更快!基本R的低效率在哪里?

这怎么可能?



其实我完全相反结果与此相比:为什么foreach()%有时候会比较慢 foreach 当按顺序使用时使用编译器来产生编译字节码,使用非导出函数 make.codeBuf cmp 。你可以使用 cmpfun 来编译内核到字节码来模拟这个并获得类似的加速。

 (p in 1:2){
for(i in 1:500){code> f.original < - function(){
x < - 0
{
for(j in 1:5000){
x< - x + i * j
}
}
}
x
}

f.foreach< - function(){
x< - 0
foreach(p = 1:2,.combine = rbind)%do%
(i in 1:500){
for(j in 1:5000){
x< - x + i * j
}
}
x $ b $ (x){

f.cmpfun< - function(x){
f< - cmpfun (b为1:5000){
x< -x + i * j
}
}
x
})
f(f( 0))
}

结果

  library(microbenchmark)
microbenchmark(f.original(),f.foreach (),f.cmpfun(),times = 5)
单位:毫秒
expr min lq中位数uq max neval
f.original()4033.6114 4051.5422 4061.7211 4072.6700 4079.0338 5
f.foreach()426.0977 429.6853 434.0246 437.0178 447.9809 5
f.cmpfun()418.2016 427.9036 441.7873 444.1142 444.4260 5
all.equal(f.original(),f.foreach(),f.cmpfun ))
[1] TRUE


This is really blowing my mind. The basic loop takes like 8 seconds on my computer:

system.time({
x <- 0
for (p in 1:2) {
    for (i in 1:500) {
        for (j in 1:5000) {
            x <- x + i * j
        }
    }
}
})
x

Whereas if I use foreach in non-parallel mode, it does take only 0.7 secs!!!

system.time({
x <- 0
foreach(p = 1:2, .combine = rbind) %do% 
    for (i in 1:500) {
        for (j in 1:5000) {
            x <- x + i * j
        }
    }
})
x

The result is the same, but foreach was somehow able to reach it much faster than basic R! Where is the inefficiency of basic R?

How is this possible?

In fact, I got complete opposite result compared to this one: Why is foreach() %do% sometimes slower than for?

解决方案

foreach when used sequentially eventually uses compiler to produce compiled byte code using the non-exported functions make.codeBuf and cmp. You can use cmpfun to compile the innerloop into bytecode to simulate this and achieve a similar speedup.

f.original <- function() {
x <- 0
for (p in 1:2) {
    for (i in 1:500) {
        for (j in 1:5000) {
            x <- x + i * j
        }
    }
}
x
}

f.foreach <- function() {
x <- 0
foreach(p = 1:2, .combine = rbind) %do% 
    for (i in 1:500) {
        for (j in 1:5000) {
            x <- x + i * j
        }
    }
x
}

f.cmpfun <- function(x) {
f <- cmpfun(function(x) {
    for (i in 1:500) {
        for (j in 1:5000) {
            x <- x + i * j
            }
        }
        x
    })
    f(f(0))
}

Results

library(microbenchmark)
microbenchmark(f.original(),f.foreach(),f.cmpfun(), times=5)
Unit: milliseconds
         expr       min        lq    median        uq       max neval
 f.original() 4033.6114 4051.5422 4061.7211 4072.6700 4079.0338     5
  f.foreach()  426.0977  429.6853  434.0246  437.0178  447.9809     5
   f.cmpfun()  418.2016  427.9036  441.7873  444.1142  444.4260     5
all.equal(f.original(),f.foreach(),f.cmpfun())
[1] TRUE

这篇关于为什么R循环比使用foreach慢10倍?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆