【问题标题】:Byte Compiler-optimisation in RR中的字节编译器优化
【发布时间】:2015-04-19 21:08:08
【问题描述】:

考虑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)

【问题讨论】:

  • R 不是编译语言;它被解释了。

标签: r performance optimization compilation compiler-optimization


【解决方案1】:

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

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“编译”它们,结果不会有太大变化

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 位)

【讨论】:

  • 对实际编译这些有用,例如,f1c = compiler::cmpfun(f1)
  • 那么,f1f2f3 在计算时间上的差异只是随机波动的问题,以及解释语言的时间,对吗?从本质上讲,R 很聪明,并且知道这三个函数做的事情完全相同,我说对了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 2011-08-24
相关资源
最近更新 更多