本文對應《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):
指那些線程與線程之間不須要進行交互的並行方式,它們每每只須要將原始的程序稍加修改便可實現並行。這樣,不只編寫簡單,並且有着極地的通訊開銷。
靜態和動態任務分配:
整體來講,動態任務分配由於有可能產生嚴重的緩存開銷,所以實際上性能不如靜態分配。