這段時間學習了<R高性能編程>這本書,基於這段時間做的項目實踐,總結了一些自己的體會,和大家分享
一、為什么R程序有時候會很慢?
1、計算性能的三個限制條件 cpu ram io R代碼本身
2、R是運行時解釋的 在運行時解釋並執行R代碼
3、R是單線程的 CPU的強大核心並沒卵用,R只會只用一個
4、R需要將全部數據加載到內存 處理的最大數據了取決於內存的限制
這里 linux相比於windows有一個優勢,當我們試圖裝載一個可用內存大小的數據集
數據可能會成功裝載,不過一旦可用內存耗盡,操作系統會將內存中的數據換到磁盤(交換空間)上
的交換文件,R人為數據全部裝載入內存時間上OS正在做內存和磁盤文件的數據交換工作,如此一來,磁盤IO瓶頸對R性能就有着巨大的影響
5、算法設計影響時間和空間復雜度
時間復雜度:運行R程序需要的計算時間和數據規模之間的關系
空間復雜度:運行R程序需要的內存量和數據規模之間的關系
二、衡量代碼的性能常用辦法
使用system.time() benchmark() microbenchmark()
Rprof() 的工作原理是在運行R表達式的時候 ,觀察R的調用棧,並以固定的時間,默認是0.02秒,對調用棧進行快照
,從而確定函數當前正在執行什么操作。通過這些快照,summaryRprof 能夠計算每個函數的耗時
要理解R程序各個部分的性能,快速發現瓶頸,Rprof 是個很有用的工具
內存分析 memory.profiling=TRUE 這個指標會有誤導,會偏高,因為有些函數內存尚未釋放,
三、加快R運行的簡單方法
1、盡量向量化運算,避免循環
2、使用內置函數。 R中存在很多低級運算符,雖然這些運算符可以組成更加復雜的運算符或者函數,但是和編譯性語言相比性能很差,
但是R提供了很多C++編寫的計算包。
比如計算 矩陣每一行的和,一般用apply可以解決問題,但是內置函數 rowSums,性能提升11倍,rowSums是使用C預編譯的優化函數
開源社區開發了很多函數優化庫供R使用,比如 basic linear algebra subprograms (BLAS) 詳見:www.netlib.org.blas
3、預分配內存
為什么要預分配內存呢?主要是因為動態分配內存會拖慢程序的運行速度,每當向量大小發生變化,程序都需要做一些額外的工作
經過測試在一個簡單的加法運算中,1000 長度的向量的計算,預分配內存之前為25.373秒,之后為0.577 秒
4、使用簡單的數據結構
5、使用更加簡單的數據結構
比如 如果可以的話,盡量使用matrix 而不是 dataframe,因為大部分矩陣操作首先要把dataframe強制轉換為matrix,才開始計算。
如果數據中存在多種變量類型,不可避免的要使用dataframe的時候,盡量用subset 和 which 篩選子集后再做運算。
6、使用哈希表進行大型數據上的頻繁查找
一個包含N個元素的列表上的查找操作的時間復雜度是O(N) 列表越靠后,查找時間越長,隨着N的增加,情況越嚴重。
CRAN 上可用的R 包是hash, 哈希表上查找操作的時間復雜度為O(1)
7、去CRAN上尋找更快的包
例如:fastcluster,princomp,fastmatch,RcppEigen,data.table,dplyr
四、使用編譯代碼加快運行速度
1、在運行之前編譯R代碼 因為每次運行前都需要解析和評估代碼。這需要話費大量CPU時間,拖慢運行速度。
利用compiler 包,能在一定程度上減少此問題,提前預編譯。
cmpfun 編譯函數
compile 編譯表達式
cmpfile 編譯存儲在文件中的R表達式
2、即時編譯 激活JIT(just in time) compiler 包的enableJIT
3、在R中使用編譯語言 在R中嵌入C、C++、OC、OC++(inline包)
4、調用外部編譯代碼 Rcpp rJava
5、使用編譯代碼的注意事項
6、創建R對象及垃圾回收
預分配變量內存,PROTECT防止R的垃圾收集器清理對象。 UNPROTECT 解除已分配內存的保護
五、使用GPU讓R運行的更快
這里需要注意的是在計算pearson相關性的時候,GPU是比CPU慢的
1、GPU最大的優勢是核心數量巨多,所以最適合數據的並行問題,不適合那些線程之間需要大量同步的任務。
2、GPU的性能主要取決於主內存(RAM)和GPU內存之間的數據傳輸量,因為RAM和CPU內存之間的連接寬帶很低。
優秀的GPU編程應該最小化這種傳輸
----------好了,截止到這里 我們已經了解了R為什么會慢以及如何衡量R代碼的性能的問題;並且突破了CPU 限制,提升R程序性能的技術。
后面會以內存和IO方面作為突破口來優化代碼,未完待續.....
原文出處:http://www.cnblogs.com/qiaoyihang/p/7779144.html