SQL データベースからデータをロードして計算を実行するための R スクリプトと Pentaho (PDI) ETL 変換の両方があります。初期データセットには、21 変数の 128 万行があり、R と PDI の両方で同等です。実際、私は最初に R コードを作成し、その後 PDI の変換に "移植" しました。
PDI 変換は 30 秒で実行されます (出力を別の DB テーブルに書き込む追加の手順が含まれます)。R スクリプトには、合計で 45 分から 1 時間かかります。R はスクリプト言語であるために解釈されることは理解していますが、ここで最適化の機会を逃しているようです。
コードの概要は次のとおりです。
sqlQuery()
パッケージを使用して SQL DB からデータ フレームにデータを読み込むRODBC
(~45 秒)str_trim()
列の 2 つ (~2 - 4s)split()
データをパーティションに分割して、定量計算を実行する準備をします (別の関数) (~30m)parLapply()
(~15-20m)を使用して、データの各パーティションに対して計算関数を並行して実行します結果を 1 つの結果データ フレーム (~10 - 15m) にまとめて rbind します。
、andddply()
の代わりに使用してみましたが、完了せずに数時間 (>3) 実行されました。また、SQL select ステートメントを変更して、パフォーマンスを向上させるために、2 つの列の一意のペアに基づく行の密なランクである人工的なグループ ID を返すようにしました。しかし、期待した効果は得られなかったようです。と を使用してみましたが、これも何時間も実行されました。split()
parLapply()
rbind()
isplit()
foreach() %dopar%
PDI 変換は Java コードを実行していますが、これは一般的に R よりも間違いなく高速です。しかし、同等の R スクリプトは、1 時間以上ではなく、10 分以内 (つまり、PDI/Java よりも 20 倍遅い) で済むようです。
他の最適化手法について何か考えはありますか?
更新: 上記のステップ 3 はsplit()
、ここで提案されているようにインデックスを使用することで解決されました R で分割するための高速な代替手段
更新 2:mclapply()
の代わりに使用してみましたがparLapply()
、ほぼ同じです (~25m)。
更新 3: 2 秒未満rbindlist()
で実行する代わりに、ステップ 5 を解決します。rbind()