提高R程序效率方法探讨

 

本期内容导读

 

150行代码写出游戏2048,哪种语言能实现?答案是R语言。虽然R语言并不适合做游戏开发,但是R语言中的向量计算,能极大地简化算法的复杂度,可以高效的完成计算任务。掌握R中的计算方法,将会起到事半功倍的效果。本周将给大家介绍R语言中计算方法的选择与程序效率的提高。

1 读取大文件

不管我们用什么软件来进行计算,首先得读入数据,对于R语言是消耗内存的软件,我们首先应该了解自己电脑的内存是否能够处理这些数据,怎样从大数据中读取我们需要的数据。

首先我们想的是用read.table或者read.csv读文件,那么对于文件过大,而我们只需要文件的部分内容,read.table的效率怎样呢? 假设文件的内容是这样的:

 

而此文件的大小是200M,而用read.csv 读取该文件需要的时间为:

 t1=Sys.time()
 data=read.table('~/desktop/finance-project/app/st.csv')
 times=Sys.time()-t1
 times
## Time difference of 3.539517 mins

对于过大的文件,我们可以进行分块读取,那么我们可以先用readLines函数读取指定行数的内容,再用read.table函数读读出的内容进行处理。

readfile<-function(){ 
pt<-file("~/desktop/finance-project/app/st.csv","r")
name=strsplit(readLines(pt,1),split=',')[[1]]; #读取标题
f1=readLines(pt,10000)
data=NULL
data=rbind(data,read.table(text=f1,sep=',',col.names=name))

close(pt)
data }

t2=Sys.time()
data=readfile()
Sys.time()-t2
## Time difference of 0.677892 secs

从上面的程序可以看出,通过分块读数据的方法,具有较强的灵活性,能明显提高读取文件的性能,这样占用的计算机内存也较小。

2 算法选择

有了数据,算法才能发挥最大的作用,而好的算法能提高计算机的性能,也能提高效率。比如在求解方程组的解时,对于小于10的未知数的方程组,我们可以采用克莱姆法则来求解,但是对于未知数不断的增大,那么克莱姆法则求解方程组的效率将变得非常低下。 如下面所示: 采用克莱姆法则求解方程组随未知数的增加计算时间的趋势图:

组随未知数的增加计算时间的趋势图:

times=sapply(c(2:100),function(n){
       t1=Sys.time()
       A=matrix(rnorm(n*n),nrow=n,ncol=n,byrow=T)
       B=rnorm(n)
       sapply(c(1:n),function(i,A,B)
                    {
                      C=A
                      C[,i]=B
                      det(C)/det(A)
                    }
         A=A,B=B)
                         
         Sys.time()-t1} )
plot(x=2:100,y=times*60,xlab='n',ylab='time',col='red')

从上图可以看出,随着未知数N的增大,与时间呈大致的指数关系。

而采用雅可比迭代的方式求解方程组的数值解:

   XY=function(n){
     eps=10^-6
     A=matrix(rnorm(n*n),nrow=n,ncol=n)
     b=rnorm(n)
     X0=rep(0,n)
     X1=sapply(c(1:n),function(i,A,b,X0)
       A[i,-i]%*%X0[-i]+b[i],A=A,b=b,X0=X0
               )
     while(max(abs(X0-X1))>eps){
       X0=X1
       X1=sapply(c(1:n),function(i,A,b,X0)
       (-A[i,-i])%*%X0[-i]+b[i],A=A,b=b,X0=X0
               )
       if(is.na(max(abs(X0-X1))))
         break
     }
       X1        
   } plot(x=2:100,y=times*60,xlab='n',ylab='time',col='red')
times=sapply(c(2:100),function(n){ t1=Sys.time() XY(n) Sys.time()-t1 } )
lines(x=c(2:100),y=times,col='blue')

从上图可以看出,采用迭代法求解方程组的时间复杂度与未知数呈线性关系,而与克莱姆法则相对,当未知数较大时,采用迭代法求解效率快,N值较小时,克莱姆法则与迭代法均可。 要得到更加精确的结果,可以采购蒙特卡洛方法进行模拟。

从上图可以看出,采用迭代法求解方程组的时间复杂度与未知数呈线性关系,而与克莱姆法则相对,当未知数较大时,采用迭代法求解效率快,N值较小时,克莱姆法则与迭代法均可。 要得到更加精确的结果,可以采购蒙特卡洛方法进行模拟。

小结:

那么,可以看出,选择合适的算法,对于计算的性能会有所提高。但具体算法还是要看实际情况。而实际中的算法可能还要实际的相关业务相结合,而想法的性能和稳定性就更重要了,那么进行单元测试就非常重要了。

在一下周将给大家讲解怎样利用R的shiny包进行交互性设计开发。

posted @ 2015-06-24 11:30  payton数据之旅  阅读(379)  评论(0)    收藏  举报