如何获取R中代码的运行效率

对于如何测试R代码的运行效率,首先可能想到的就是proc.time()以及system.time()了。

我们来看代码:

> ptm <- proc.time()
> for (i in 1:50) mad(stats::runif(500))
> proc.time() - ptm
   user  system elapsed 
  0.022   0.002   0.038 
> system.time(for(i in 1:100) mad(runif(1000)))
   user  system elapsed 
  0.025   0.002   0.028

这两个函数都只适合测试一整块代码的运行效率。

还有可以想到的工具应该就是rbenchmark了。

> random.array = function(rows, cols, dist=rnorm) 
+                   array(dist(rows*cols), c(rows, cols))
> random.replicate = function(rows, cols, dist=rnorm)
+                       replicate(cols, dist(rows))
> benchmark(replications=rep(100, 3),
+           random.array(100, 100),
+           random.array(100, 100),
+           columns=c('test', 'elapsed', 'replications'))
                    test elapsed replications
1 random.array(100, 100)   0.093          100
2 random.array(100, 100)   0.094          100
3 random.array(100, 100)   0.093          100
4 random.array(100, 100)   0.096          100
5 random.array(100, 100)   0.092          100
6 random.array(100, 100)   0.093          100

rbenchmark比较适合比较不同块代码之间的执行效率。

如果你写了一个函数,你想查看每一行代码的运行效率,那可能之前的函数都不十分合适。为此,我写了一段代码,用于查看多行代码每行的执行效率,以提高在开发过程中查找执行瓶颈的效率。

######################################################
#by Jianhong Ou @ umassmed @ quiworld @ Oct 18, 2013
######################################################
FST_TIMER_ELAPSED <- proc.time()
FST_TIMER_EXPR <- list(start="start")
counter <- function(){	
	function(expr, value, ok, visible){
		FST_TIMER_ELAPSED <- get("FST_TIMER_ELAPSED", envir=.GlobalEnv)
		FST_TIMER_ELAPSED <- rbind(FST_TIMER_ELAPSED, proc.time())
		assign("FST_TIMER_ELAPSED", FST_TIMER_ELAPSED, envir=.GlobalEnv)
		assign("FST_TIMER_EXPR", c(get("FST_TIMER_EXPR", envir=.GlobalEnv), expr), envir=.GlobalEnv) 
		return(TRUE)
	}
}
 
h <- taskCallbackManager()
h$add(counter(), name="timeCounter")
 
 
################## start code to be tested ##################
rep=random.replicate(100, 100)
arr=random.array(100, 100)
################## end code to be tested ##################
 
removeTaskCallback("R-taskCallbackManager")
FST_TIMER_ELAPSED[2:nrow(FST_TIMER_ELAPSED),1:3] <- FST_TIMER_ELAPSED[2:nrow(FST_TIMER_ELAPSED),1:3] - FST_TIMER_ELAPSED[1:(nrow(FST_TIMER_ELAPSED)-1), 1:3]
FST_TIMER_ELAPSED[1, 1:3] <- c(0,0,0)
 
FST_TIMER_ELAPSED
FST_TIMER_EXPR
cbind(as.data.frame(FST_TIMER_ELAPSED[,1:3]), as.character(FST_TIMER_EXPR))

方法2

######################################################
#by Jianhong Ou @ umassmed @ quiworld @ Oct 18, 2013
######################################################
FST_TIMER_ELAPSED <- proc.time()
counter <- function(){    
    function(expr, value, ok, visible){
        FST_TIMER_ELAPSED.old <- get("FST_TIMER_ELAPSED", envir=.GlobalEnv)
        FST_TIMER_ELAPSED.new <- proc.time()
        elapsed <- FST_TIMER_ELAPSED.new - FST_TIMER_ELAPSED.old
        assign("FST_TIMER_ELAPSED", FST_TIMER_ELAPSED.new, envir=.GlobalEnv)
        print(elapsed)
        return(TRUE)
    }
}
h <- taskCallbackManager()
h$add(counter(), name="timeCounter")
 
 
################## start code to be tested ##################
rep=random.replicate(100, 100)
arr=random.array(100, 100)

方法3

######################################################
#by Jianhong Ou @ umassmed @ qiubio @ May 11, 2016
######################################################
options("FST_TIMER_ELAPSED"=proc.time()[3L])
counter <- function(){    
    function(expr, value, ok, visible){
        pt <- function(s){
                h <- floor(s/3600)
                m <- floor((s - 3600*h)/60)
                ss <- floor(s - 3600 * h - 60*m)
                s <- formatC(floor((s - 3600 * h - 60*m - ss)*1000), width=3, flag=0)
                paste(h, m, ss, s, sep=":")
        }
        FST_TIMER_ELAPSED.new <- proc.time()[3L]
        FST_TIMER_ELAPSED.old <- getOption("FST_TIMER_ELAPSED")
        elapsed <- FST_TIMER_ELAPSED.new - FST_TIMER_ELAPSED.old
        options("FST_TIMER_ELAPSED"=proc.time()[3L])
        options("prompt"=paste(format(Sys.time(), "%H:%M:%S"), pt(elapsed), "> "))
        return(TRUE)
    }
}
h <- taskCallbackManager()
h$add(counter(), name="timeCounter")
 
 
################## start code to be tested ##################
rep=random.replicate(100, 100)
arr=random.array(100, 100)

Leave a Reply

  

  

  

%d 博主赞过: