R 中的字节编译器优化

Byte Compiler-optimisation in R

考虑 R 中的以下代码

####### CODE 1 #######

test = FALSE # or TRUE
for (i in 1:10^5){
   if (test){
      DoThat(i)
   } else {
      DoThis(i)
   }
}

如果 R 编译器很好,我希望 if 语句的条件不会在每次迭代时都被评估。 Code 1 将等同于

####### CODE 2 #######

test = FALSE # or TRUE
if (test){
  for (i in 1:10^5){
      DoThat(i)
  }
} else {
  for (i in 1:10^5){
      DoThis(i)
  }
}

Code 1 更容易阅读,但如果编译不好会比 code 2

这两个代码编译后是否等价(计算时间)?我是否应该确保将我的代码包含到一个函数中(最终是一个名为 main 的函数)以确保编译得到很好的优化?

仅供参考:我的 R 版本是 R 3.1.2 GUI 1.65 Mavericks build (6833)

这似乎是您可以轻松地对自己进行基准测试的东西(我会在组合中加入另一个选项

DoThis<-function(x) x+2
DoThat<-function(x) x+1

f1<-function() {
    test = FALSE # or TRUE
    for (i in 1:10^5){
        if (test){
            DoThat(i)
        } else {
            DoThis(i)
        }
    }
}

f2<-function() {
    test = FALSE # or TRUE
    if (test){
        for (i in 1:10^5){
            DoThat(i)
        }
    } else {
        for (i in 1:10^5){
            DoThis(i)
        }
    }   
}

f3<-function() {
    test = FALSE # or TRUE
    if (test){
        fn<-DoThat
    } else {
        fn<-DoThis
    }
    for (i in 1:10^5){
        fn(i)
    }
}

然后与

比较
library(microbenchmark)
microbenchmark(f1(),f2(),f3())

# Unit: milliseconds
#  expr      min       lq     mean   median       uq      max neval cld
#  f1() 55.44489 57.79875 61.50379 60.65098 62.25607 118.8442   100   b
#  f2() 42.70537 44.30422 52.45846 46.37495 48.51268 499.1535   100  ab
#  f3() 41.59938 42.92486 47.29460 46.02898 47.50596 117.2711   100  a 

如您所见,它们在微秒级上的 运行 时间大致相等。

如果您通过 compiler::cmpfun "compile" 他们,结果不会有太大变化

f1c = compiler::cmpfun(f1)
f2c = compiler::cmpfun(f2)
f3c = compiler::cmpfun(f3)
microbenchmark(f1c(),f2c(),f3c())

# Unit: milliseconds
#   expr      min       lq     mean   median       uq       max neval cld
#  f1c() 42.39095 45.59775 50.22462 47.38297 49.73408 132.88284   100   b
#  f2c() 41.79704 43.79836 46.87072 44.98536 48.21903 126.02609   100  a 
#  f3c() 40.07256 42.33789 45.14435 44.16019 46.32952  66.53634   100  a 

测试:R 版本 3.1.0 (2014-04-10),平台:x86_64-apple-darwin10.8.0(64 位)