本文对应《R语言编程艺术》算法
第14章:性能提高:速度和内存;数据库
第15章:R与其余语言的接口;编程
第16章:R语言并行计算数组
=========================================================================缓存
性能提高:速度和内存app
要使R代码运行速度更快,有如下建议:函数
消除显示循环:性能
采用向量化提高速度,由于采用显示循环涉及屡次函数调用和迭代,耗费时间,而向量化函数内部是用编译型语言实现,所以会提高速度。优化
经常使用的加速代码的向量化函数:ifelse() /which() /where() /any() /all() /cumsum() /cumprod()等函数;用于矩阵的rowSums() /colSums()等函数;用于穷举全部组合问题的combn() /outer() /lower.tri() /upper.tri() /expand.grid()等函数。spa
尽管apply()能够消除显式循环,但它其实是用R而不是C实现的,所以它一般并不能加速代码,只是使代码更加紧凑。然而,其余的apply函数,如lapply(),对于加速代码是很是有帮助的。
利用Rprof()来寻找代码的瓶颈:
首先调用Rprof()来开启监视器,而后运行代码,再调用带NULL参数的Rprof()来结束监视。最后,调用summaryRprof()来查看结果。
内存管理:
数据分块:read.table()函数的skip参数设置,能够分块读取数据。
R软件包的内存管理:RMySQL,提供R与MySQL的接口,将选择数据的操做放在数据库端;biglm包,能够在很是大的数据集上进行回归和广义线性模型的分析;ff包,经过将数据存放在硬盘上来回避内存的限制;bigmemory包,功能相似,但它不只能够将数据存储在硬盘上,还能够将数据保存在机器的主内存中,这对于多核的机器而言是一个理想的选择。
=========================================================================
R与其余语言的接口
能被R调用的C/C++函数:
通常而言,这样作的目的是提高程序的性能;另外一个缘由是使用特殊的I/O操做(例如R使用的TCP协议速度不如C/C++使用的UDP协议)。
接口能够经过.C()或.Call()实现。.Call()提供了更全面的功能,但使用它须要对R的内部结构有所了解。
注意:C语言中,二维数组是按行进行存储的,而在R中则是按列存储;C语言下标是从0开始,而在R中是从1开始。
从Python调用R:
Python缺乏内置的统计和数据处理功能,能够经过R来弥补。
RPy是一个Python模块,容许在Python中使用R。若是但愿有额外的性能提高,则能够考虑与NumPy共同使用。
语法:R中的对象(函数)名冠上r.前缀。
注意:Python的语法中没有波浪号,所以在指定模型表达式时须要使用字符串;
须要一个数据框来包含数据;
若是R的函数名中带有英文句点,那么须要在Python中改成下划线。
>>> r.library(‘lattice’) >>> r.assign(‘a’, a) >>> r.assign(‘b’, b) >>> r(‘g <- expand.grid(a, b)’) >>> r(‘g$Var3 <- g$Var1^2 + g$Var1 * g$Var2’) >>> r(‘wireframe(Var3 ~ Var1 + Var2, g)’) >>> r(‘plot(wireframe(Var3 ~ Var1 + Var2, g))’)
=========================================================================
R语言并行计算
Snow包简介:主要过程:
OpenMP包:
利用R调用并行化的C
经常使用指令:
#pragma omp barrier |
迭代型算法中经常使用,线程将在屏障处进行等待,直到每次迭代的结束 |
#pragma omp critical { // place one or more statements here } |
紧接着这一指令的代码块称为一个“关键区域”(critical section),意思是在这个区域中同时只容许一个线程执行这段代码 |
#pragma omp single { // place one or more statements here } |
紧接着这一指令的代码块将只被一个线程执行 |
简单并行(embarrassingly parallel):
指那些线程与线程之间不须要进行交互的并行方式,它们每每只须要将原始的程序稍加修改便可实现并行。这样,不只编写简单,并且有着极地的通讯开销。
静态和动态任务分配:
整体来讲,动态任务分配由于有可能产生严重的缓存开销,所以实际上性能不如静态分配。