mmapパッケージを使って
お手軽オブジェクト管理
  2011年11月26日
     Japan.R LT
      @sfchaos
自己紹介



� データ分析コンサルタント
� 一昔前はRやC++で金融工学
� 最近はヘルスケア関連の分析


                   2
Rの問題点としてよく聞く話
  「Rはオンメモリだから
 大規模データは無理・・・」


                 3
確かに1オブジェクトが
  数10GB~TBクラスの
 データをRで扱うのは難しい

※ Revolution Analytics, bigmemory, ffなどを
     使う手はあるが,機能が限定的


                                           4
だが,手元で分析する場合は,
複数のオブジェクトが積み重なり
メモリを逼迫することも少なくない
      (体験談)

                   5
それなら,必要なときに
read.csv(or read.table/scan)
       で読み込もう!


                               6
遅っ・・・!
               (CPU: Intel Core i7)

> # Data Expo 2009のデータを読み込む(2008年度分)
> system.time(x <- read.csv("../data/2008.csv"))
    ユーザ システム              経過
   70.790     6.730     78.874


                                                   7
あるいはsave/load関数で
バイナリ形式で保存・読み込む



                    8
この方法は
 データ全体を読み込むので
オブジェクトが不要になったら
人力で削除しなければならない

                 9
そんなとき役立つかもしれないのが
    mmapパッケージ!



               10
> # Data Expo 2009のデータ(2008年度分,657MB)
> system.time(x <- read.csv("../data/2008.csv"))
    ユーザ システム              経過
   70.790      6.730    78.874
> object.size(x)
813470376 bytes
> gc()
             used (Mb)   gc trigger (Mb)   max used (Mb)
Ncells    181957 9.8      407500    21.8    350000 18.7
Vcells 101932893 777.7 310681082 2370.4 310100488 2365.9




                                                           11
確かに最初はmmap形式にデータを
   変換するのに時間はかかるが
 一旦生成すればメモリへの負担は軽い
> system.time(y <- as.mmap(x, file="2008.mmap"))
    ユーザ        システム        経過
   26.340     75.590 352.476
> object.size(y)
264 bytes
> rm(x)


                                                   12
データフレームで読みこんだ後に
 mmapに変換するのではなく,
フラットファイルから直接mmapに
      変換したい

                    13
mmap.csvという関数があるが,
      うまくいかず・・・



                     14
とは言うものの,
やはり巨大なデータも扱いたい!



                  15
bigmemoryパッケージ周辺の機能を
         拡張したい!



                   16
class BigDataFrame : boost::noncopyable
{
  public:
   enum DataType {CHAR=1, SHORT=2, INT=3, DOUBLE=4, COMPLEX=5};
 public:
  BigDataFrame(index_type nrow, index_type ncol) : nrow_(nrow), ncol_(ncol) {
   // initializing shared pointer
   p = std::shared_ptr<Monitor>(new Monitor[ncol],
                       std::default_delete<Monitor[]>());


 まずはbigmemoryのデータフレーム
  版を目指して開発していきたい
                    期待せずに待っていてください・・・
                              template <typename T>
                              struct RecordValueVisitor : boost::static_visitor<>
                              {
                                RecordValueVisitor(T const& v) : val_(v) { }
                                void operator ()(std::vector<T>& vec) const {
                                  vec.push_back(this->val_);
                                }
                                private:
                                T val_;
                              };
                                                                                    17

mmapパッケージを使ってお手軽オブジェクト管理