Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Rの高速化 Kashiwa.R#1  11 / 11 / 11 @antiplastics
自己紹介所属: 東京理科大学大学院    薬学研究科    修士課程2年 (来年からD進学予定)専門: バイオインフォマティクスtwitterアカウント: @antiplastics趣味: バイク、サーフィン、アニメ、読書など研究内容: マイク...
扱っているデータの構造              実験1    実験2    実験3            実験287   実験288   実験289    遺伝子1      1.7    3.9     4.8            4.4...
データ解析の現場の実情     動画
遅い!!!(ノ; _ ;)ノ ┫:・.::結果待ちに数日かかる事もたびたび。計算が速く終わるかどうかは死活問題。
Rはパッケージがとても豊富。library(“hogehoge”)とか打ったら小難しい計算も、関数が勝       手にやってくれるからコード行数も少なくて済む。                   めちゃくちゃ便利!  だが現実問題これだけ遅...
使用するマシン  iMac(21.5inch)    OS: MacOSⅩ10.6.8         SnowLeopard(64bit)    CPU: 2.8GHz           Intel Corei7(コア数:4)    メモリ...
比較する計算以下の数値積分(中点法)により近時的に円周率 πを求める。         =             N(ステップ数)が増すほど精度が上がる             今回は1千万(107)ステップで計算する
Cのソースコード#include<stdio.h>#include<time.h>#define num_steps 10000000           107という値をとる変数num_stepsを定義int main(void){   cl...
Perlのソースコード$t1 = (times)[0];$num_steps = 10000000;$step = 1.0 / $num_steps;        for($i = 1;$i <= $num_steps; $i++){    ...
Pythonのソースコードimport sysimport timebefore = time.time()num_steps = 10000000sum = 0step = 1.0 / num_stepsfor i in range(1,nu...
Rubyのソースコードrequire "benchmark"num_steps = 10000000step = 1.0 / num_stepssum = 0puts Benchmark::CAPTIONputs Benchmark.measu...
結果    ランク   言語     実行時間(s)     1    C        0.15     2    Python   5.19     3    Perl     5.59     4    Ruby     9.12やはりC...
R <R-2.12.1,64bit> のソースコード                        *このくらいのステップ数だと32bitのRは使えなくなるので注意。before <- proc.time()num_steps <- 10000...
結果      ランク   言語     実行時間(s)       1    C        0.15       2    Python   5.19       3    Perl     5.59       4    Ruby   ...
Rの高速化手法① プログラム修正before <- proc.time()num_steps <- 1:10000000           num_stepsを変数からベクトルへ変更  step <- 1.0 / 10000000      ...
結果      ランク   言語         実行時間(s)       1    C            0.15new    2    R(プログラム修正)   0.30       3    Python       5.19   ...
Rの高速化手法② apply関数の使用apply関数ファミリー①で行なったベクトル、行列に同時にアクセスするような計算を、より明示的にできる関数。入力データの型、出力データの型の違いなどで、apply(),lapply(), sapply(),...
Rの高速化手法② apply関数の使用before <- proc.time()num_steps <- 1:10000000step <- 1.0 / 10000000menseki <- function(A){        x <- (...
結果      ランク   言語         実行時間(s)       1    C            0.15       2    R(プログラム修正)   0.30       3    Python       5.19   ...
Rの高速化手法③ 並列化           snowパッケージを使えば、先程のapply関数が並列に計算できる!applyファミリー          snowのでのapplyファミリーapply()             parApply...
Rの高速化手法③ 並列化before <- proc.time()library("snow")library(“Rmpi”)                              snowによりMPIクラスターを4個生成cl <- mak...
結果      ランク   言語           実行時間(s)       1    C               0.15       2    R(プログラム修正)      0.30       3    Python      ...
Rの高速化手法④ ffパッケージ      Rはメモリを逼迫させる。→データはハードディスクから、必要に応じてメモリに         ロードしたい。*ベクトル、行列、因子などのデータ: ffパッケージ  *行列のデータ: bigmemoryパ...
Rの高速化手法④ ffパッケージbefore <- proc.time()library(ff)library(snowfall)sfInit(parallel=TRUE, cpus=4,type=“MPI")         4つのクラスター...
結果      ランク   言語              実行時間(s)       1    C                  0.15       2    R(プログラム修正)         0.30       3    Pyt...
Rの高速化手法⑤ バイトコンパイラーの使用                 あらかじめ構文解析後の関数にしておく。  人が見ても何しているのかわからない機械語に近い形式になる。                                  ...
Rの高速化手法⑤ バイトコンパイラーの使用before <- proc.time()library("compiler")num_steps <- 1:10000000       step <- 1.0 / 10000000menseki <...
結果      ランク   言語                    実行時間(s)       1    C                        0.15       2    R(プログラム修正)               0...
並列化と組み合わせ      ランク   言語                    実行時間(s)       1    C                         0.15       2    R(プログラム修正)        ...
Rの高速化手法⑥ R-2.14.0最新VerのR-2.14.0はかなり速い。*全ての基本パッケージの関数があらかじめ、バ イトコンパイルされているとか            R-2.4.0    30.1s            R-2.8.0...
最終結果      ランク   言語                    実行時間(s)       1    C                         0.15       2    R(プログラム修正)             ...
時間の関係でできなかった           高速化手法•   Revolution R    インストール時にコア数を勝手に調べて、マルチコア対応に計算を実行してくれる新型R    (Windows、Redhat用)。普通のRより2〜3倍速い...
Upcoming SlideShare
Loading in …5
×

Rの高速化

30,687 views

Published on

Published in: Technology

Rの高速化

  1. 1. Rの高速化 Kashiwa.R#1 11 / 11 / 11 @antiplastics
  2. 2. 自己紹介所属: 東京理科大学大学院 薬学研究科 修士課程2年 (来年からD進学予定)専門: バイオインフォマティクスtwitterアカウント: @antiplastics趣味: バイク、サーフィン、アニメ、読書など研究内容: マイクロアレイデータからの 発現変動遺伝子の検出
  3. 3. 扱っているデータの構造 実験1 実験2 実験3 実験287 実験288 実験289 遺伝子1 1.7 3.9 4.8 4.4 2.5 4.8 実験特異的遺伝子 遺伝子2 -3.3 -0.2 0.2 -4.1 3.1 3.1 発現の検出 など 遺伝子5547 -1.2 4.6 -0.9 4.6 -4.4 1.5 遺伝子5548 1.3 2.7 1.6 6.1 -1.4 3.1 遺伝子5549 2.2 3.2 -1.4 1.3 -3.2 2.0 発現変動遺伝子の検出 など 行 (生物の遺伝子数) 列 (実験データの数)*原核生物(大腸菌、緑膿菌など) *ますます増加するデータベースへの登録件数 6000gene *真菌(カビ、酵母など) × *NGS(次世代シーケンサ)の登場 10000gene *真核生物(ヒト、マウスなど) 20000gene 超多次元、多変量の大規模データ!!
  4. 4. データ解析の現場の実情 動画
  5. 5. 遅い!!!(ノ; _ ;)ノ ┫:・.::結果待ちに数日かかる事もたびたび。計算が速く終わるかどうかは死活問題。
  6. 6. Rはパッケージがとても豊富。library(“hogehoge”)とか打ったら小難しい計算も、関数が勝 手にやってくれるからコード行数も少なくて済む。 めちゃくちゃ便利! だが現実問題これだけ遅いと、やってられない時も。 →Rを高速化させて、サクサク研究を進めたい!! →速くしようと思ったらどこまで速くなるかをみてみよう。
  7. 7. 使用するマシン iMac(21.5inch) OS: MacOSⅩ10.6.8 SnowLeopard(64bit) CPU: 2.8GHz Intel Corei7(コア数:4) メモリ: 8GB HDD: 1TB 以下全てのプログラムはこのマシン上 で走らせる事とする。
  8. 8. 比較する計算以下の数値積分(中点法)により近時的に円周率 πを求める。 = N(ステップ数)が増すほど精度が上がる 今回は1千万(107)ステップで計算する
  9. 9. Cのソースコード#include<stdio.h>#include<time.h>#define num_steps 10000000 107という値をとる変数num_stepsを定義int main(void){ clock_t t1, t2; t1 = clock(); int i; double x,pi,sum=0.0,step; step = 1.0 / (double) num_steps; ステップ = 1/107を定義 for(i = 1;i <= num_steps; i++){ x = (i - 0.5) * step; sum = sum + 4.0 / (1.0 + x * x); 各ステップ毎に長方形の面積を } 計算し、最後に和を求める pi = step * sum; printf("%f¥n",pi); t2 = clock(); printf("%f¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); return(0);}
  10. 10. Perlのソースコード$t1 = (times)[0];$num_steps = 10000000;$step = 1.0 / $num_steps; for($i = 1;$i <= $num_steps; $i++){ $x = ($i - 0.5) * $step; $sum = $sum + 4.0 / (1.0 + $x * $x); } $pi = $step * $sum; print $pi; print "¥n";$t2 = (times)[0];$t3 = $t2 - $t1;print "$t3 秒¥n";
  11. 11. Pythonのソースコードimport sysimport timebefore = time.time()num_steps = 10000000sum = 0step = 1.0 / num_stepsfor i in range(1,num_steps): x = (i - 0.5) * step sum = sum + 4.0 / (1.0 + x * x)pi = step * sumprint piprint "¥n"after = time.time()print "Running Time =", after - before, "s"
  12. 12. Rubyのソースコードrequire "benchmark"num_steps = 10000000step = 1.0 / num_stepssum = 0puts Benchmark::CAPTIONputs Benchmark.measure{ for i in 1 .. num_steps x = (i - 0.5) * step sum = sum + 4.0 / (1.0 + x * x) endpi = step * sumputs pi}
  13. 13. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 Python 5.19 3 Perl 5.59 4 Ruby 9.12やはりCは最速。スクリプト言語とCの差は大きい。
  14. 14. R <R-2.12.1,64bit> のソースコード *このくらいのステップ数だと32bitのRは使えなくなるので注意。before <- proc.time()num_steps <- 10000000 step <- 1.0 / num_steps summ <- 0 for(i in 1:num_steps){ x <- (i - 0.5) * step summ <- summ + 4.0 / (1.0 + x * x) } pi <- step * summ print(pi)after <- proc.time()print(after – before)
  15. 15. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 Python 5.19 3 Perl 5.59 4 Ruby 9.12new 5 R 23.28 遅い…orz
  16. 16. Rの高速化手法① プログラム修正before <- proc.time()num_steps <- 1:10000000 num_stepsを変数からベクトルへ変更 step <- 1.0 / 10000000 x <- (num_steps - 0.5) * step for文をやめて、ベクトルに pi <- sum((4.0 / (1.0 + x * x))*step) 一度にアクセスするような 書き方をする print(pi)after <- proc.time()print(after - before)
  17. 17. 結果 ランク 言語 実行時間(s) 1 C 0.15new 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R 23.28 スクリプト言語をぶち抜きましたwww
  18. 18. Rの高速化手法② apply関数の使用apply関数ファミリー①で行なったベクトル、行列に同時にアクセスするような計算を、より明示的にできる関数。入力データの型、出力データの型の違いなどで、apply(),lapply(), sapply(), mapply(), tapply() がある。
  19. 19. Rの高速化手法② apply関数の使用before <- proc.time()num_steps <- 1:10000000step <- 1.0 / 10000000menseki <- function(A){ x <- (A - 0.5) * step 各ステップで長方形の面積を求める計算は、一 y <- 4.0 / (1.0 + x * x) 度関数として定義する return(y*step)}pi <- sum(sapply(num_steps,menseki)) sapplyを使って、配列num_stepsの各要print(pi) 素に関数mensekiを適用する。after <- proc.time()print(after - before)
  20. 20. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R 23.28new 7 R(apply) 54.16かえって遅くなった…。ただし、apply関数を覚えておくといい事がある(後述)。
  21. 21. Rの高速化手法③ 並列化 snowパッケージを使えば、先程のapply関数が並列に計算できる!applyファミリー snowのでのapplyファミリーapply() parApply() #行列用lapply() parLapply() #リスト用sapply() parSapply() #ベクトル、行列用mapply() × #グループ化されたデータ用tapply() × #規則的なリストの作成× parRapply() #行列の行に対して× parCapply() #行列の列に対して× parMM() #行列同士の掛け算
  22. 22. Rの高速化手法③ 並列化before <- proc.time()library("snow")library(“Rmpi”) snowによりMPIクラスターを4個生成cl <- makeCluster(4,type=“MPI")num_steps <- 1:10000000step <- 1.0 / 10000000clusterExport(cl,”step”)menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) 各ステップで長方形の面積を求める計算 return(y*step) は、一度関数として定義する} snow内で並列化対応したsapplyであpi <- sum(parSapply(cl,num_steps,menseki))print(pi) るparSapplyを使うafter <- proc.time()print(after - before)stopCluster(cl)
  23. 23. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(snow) 17.35 7 R 23.28 8 R(apply) 54.16
  24. 24. Rの高速化手法④ ffパッケージ Rはメモリを逼迫させる。→データはハードディスクから、必要に応じてメモリに ロードしたい。*ベクトル、行列、因子などのデータ: ffパッケージ *行列のデータ: bigmemoryパッケージしかも上記の2つは並列化まであわせてやってくれる!
  25. 25. Rの高速化手法④ ffパッケージbefore <- proc.time()library(ff)library(snowfall)sfInit(parallel=TRUE, cpus=4,type=“MPI") 4つのクラスターを生成num_steps <-ff(vmode="integer",1:10000000,length=10000000) step <- 1.0 / 10000000 ff,stepを各クラスsfLibrary(ff) ターにエクスポートsfExport("step")menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) snowfall内でのsapply()である、 return(y*step) sfSapply()を使う}pi <- sum(sfSapply(num_steps,menseki))print(pi)after <- proc.time()print(after - before)
  26. 26. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(ff) 17.00 7 R(snow) 17.35 8 R 23.28 9 R(apply) 54.16 snowより若干速いくらい
  27. 27. Rの高速化手法⑤ バイトコンパイラーの使用 あらかじめ構文解析後の関数にしておく。 人が見ても何しているのかわからない機械語に近い形式になる。 バイトコンパイル後 list(.Code, list(7L, GETVAR.OP, 1L, LDCONST.OP, 2L, SUB.OP, 3L, GETVAR.OP, 4L, MUL.OP, 5L, ①library(“compiler”) SETVAR.OP, 6L, POP.OP, LDCONST.OP, ②menseki2 <- cmpfun(menseki) 7L, LDCONST.OP, 8L, GETVAR.OP, 6L, ③disassemble(menseki2) GETVAR.OP, 6L, MUL.OP, 9L, ADD.OP, 10L, DIV.OP, 11L, SETVAR.OP, 12L, POP.OP, GETVAR.OP, バイトコンパイル前 12L, GETVAR.OP, 4L, MUL.OP, 13L, RETURN.OP), list({menseki <- function(A){ x <- (A - 0.5) * step x <- (A - 0.5) * step y <- 4/(1 + x * x) y <- 4.0 / (1.0 + x * x) return(y * step) }, A, 0.5, A - 0.5, step, (A - 0.5) * step, x, 4, 1, return(y*step) x * x, 1 +} x * x, 4/(1 + x * x), y, y * step))
  28. 28. Rの高速化手法⑤ バイトコンパイラーの使用before <- proc.time()library("compiler")num_steps <- 1:10000000 step <- 1.0 / 10000000menseki <- function(A){ x <- (A - 0.5) * step y <- 4.0 / (1.0 + x * x) return(y*step)}menseki2 <- cmpfun(menseki) バイトコンパイルpi <- sum(sapply(num_steps,menseki2))print(pi)after <- proc.time()print(after - before)
  29. 29. 結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R(ff) 17.00 7 R(snow) 17.35 8 R 23.28new 9 R(compiler + apply) 41.14 10 R(apply) 54.16
  30. 30. 並列化と組み合わせ ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12new 6 R(compiler + ff) 14.41new 7 R(compiler + snow) 15.11 8 R(ff) 17.00 9 R(snow) 17.35 10 R 23.28 11 R(compiler + apply) 41.14 12 R(apply) 54.16
  31. 31. Rの高速化手法⑥ R-2.14.0最新VerのR-2.14.0はかなり速い。*全ての基本パッケージの関数があらかじめ、バ イトコンパイルされているとか R-2.4.0 30.1s R-2.8.0 30.8s R-2.9.10 31.7s R-2.10.0 31.7s R-2.11.0 24.2s 64bit化 R-2.12.1 23.28s R-2.13.2 24.4s ? R-2.14.0 ? バイトコンパイル化 の順
  32. 32. 最終結果 ランク 言語 実行時間(s) 1 C 0.15 2 R(プログラム修正) 0.30 3 Python 5.19 4 Perl 5.59 5 Ruby 9.12 6 R(compiler + ff) 14.41 7 R(compiler + snow) 15.11 8 R(ff) 17.00 9 R(snow) 17.35new 10 R(2.14.0) 22.01 11 R 23.28 12 R(compiler + apply) 41.14 13 R(apply) 54.16
  33. 33. 時間の関係でできなかった 高速化手法• Revolution R インストール時にコア数を勝手に調べて、マルチコア対応に計算を実行してくれる新型R (Windows、Redhat用)。普通のRより2〜3倍速いという噂。• RCCコンパイラー R→C++に変換できます(Windows、Linux用)。• RDBMSの利用 Rでリレーショナルデータベース(MySQL,PostgreSQL,RODBC,MiniSQL)がいじれます。• Hadoop,Mapreduceの利用 http://www.slideshare.net/holidayworking/rmapreduce (以前のTokyo.Rのスライド)• R+クラウドコンピューティング segue: アマゾンがやっているlapply関数を並列に計算してくれるサービス(Mac,Linux用)。 http://code.google.com/p/segue/

×