请考虑以下示例:
> start<-Sys.time()
> for(i in 1:10000){}
> Sys.time()-start
Time difference of 0.01399994 secs
>
> fn<-function(){
+ start<-Sys.time()
+ for(i in 1:10000){}
+ Sys.time()-start
+ }
> fn()
Time difference of 0.00199604 secs
start<-Sys.time()
for(i in 1:10000){x<-100}
Sys.time()-start
Time difference of 0.012995 secs
fn<-function(){
start<-Sys.time()
for(i in 1:10000){x<-100}
Sys.time()-start
}
fn()
Time difference of 0.008996964 secs
增加迭代次数后的结果相同,如下所示:
> sim<-10000000
> start<-Sys.time()
> for(i in 1:sim){x<-i}
> Sys.time()-start
Time difference of 2.832 secs
>
> fn<-function(){
+ start<-Sys.time()
+ for(i in 1:sim){x<-i}
+ Sys.time()-start
+ }
> fn()
Time difference of 2.017997 secs
我猜这不是巧合!为什么R代码在函数中运行得更快?
2条答案
按热度按时间jexiocij1#
R中的函数是由JIT编译器编译的。在这之后,大多数函数都会更快。
正如
?compiler::enableJIT
中的文档所说,如果参数为0,则禁用JIT。如果level为1,则在第一次使用之前编译较大的闭包。如果level为2,然后一些小的闭包在第二次使用之前也会被编译。如果level是3,那么所有顶级循环在执行之前都会被编译。JIT level 3要求编译器选项optimize为2或3。JIT级别也可以通过将环境变量R_ENABLE_JIT设置为这些值之一来启动R来选择。使用负参数调用enableJIT将返回当前JIT级别。默认JIT级别为3。
所以很多函数会比顶级代码更快。
hgb9j2n62#
为了证明JIT的影响,我使用了这个基准测试:
结果显示,禁用JIT后,执行时间几乎相同:
使用
compiler::enableJIT(3)
(默认值),函数速度更快:有趣的是,启用JIT似乎会减慢在函数外部运行的代码(与第一个“无JIT”基准测试相比),即使它不会被优化。理解为什么会很有趣(也许JIT需要时间来找出它不会优化的代码)?