質問

rcppの新機能リストの一部をコピーせずに既知の構造でRからネストされたリストを取得して使用する方法をテストしています。小さなコード例(埋め込まれたRコード付き)は機能しているようです(COUTはデバッグに使用されます)。

Rから取得されたリストRLは非常に大きくなる可能性があるので、メモリを再割り当てしたくない(RLのコピー部分)。現在のコードコピー部分はRL?

最高のLARS

#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
using namespace std;

// [[Rcpp::export]]
SEXP testing(const List rL) {
   List L(rL);
   SEXP sL2(L["L2"]);
   List L2(sL2);

   SEXP sStateGrpL2(L2["stateGroups"]);
   List stateGrpL2(sStateGrpL2);
   SEXP sStateAllocL2(L2["stateAlloc"]);   
   CharacterVector stateAllocL2(sStateAllocL2);

   SEXP sActionGrpL2(L2["actionGroups"]);
   List actionGrpL2(sActionGrpL2);
   SEXP sActionAllocL2(L2["actionAlloc"]);
   List actionAllocL2(sActionAllocL2);

   vector<string> stateLabels; 
   vector<string> actionLabels;
   CharacterVector actionNames;

   for(int n2 = 0; n2< as<int>(L2["stages"]); n2++) {
      stateLabels = as< vector<string> >(stateGrpL2[as<string>(stateAllocL2[n2])]);
      int s2Size = stateLabels.size(); 
      SEXP sAllocA(actionAllocL2[n2]);
      List allocA(sAllocA);
      actionNames = as<CharacterVector>(allocA[0]);
      cout << "stage:" << n2 << " sN:" << as<string>(stateAllocL2[n2]) << "\n";
      for (int s2=0; s2<s2Size; ++s2) { 
        cout << " s:" << stateLabels[s2] << " aN:" << actionNames[s2] << "\n";
        actionLabels = as< vector<string> >(actionGrpL2[ as<string>(actionNames[s2]) ]);
        int a2Size = actionLabels.size();
        for (int a2=0; a2<a2Size; ++a2) {
           cout << "    a:" << actionLabels[a2] << "\n";
        }
      }
   }

   return wrap(0);
}


/*** R 
L <- list( L2=list(stages=2, 
                   stateGroups=list(s1Grp=c("a","b","c"),s2Grp=c("d","e")), 
                   stateAlloc = c(rep("s1Grp",1),rep("s2Grp",1)), 
                   actionGroups = list(a1Grp=c("terminate","keep"), a2Grp=c("finish")),
                   actionAlloc = list(list( rep("a1Grp",3) ),
                                       list( c("a1Grp","a2Grp") )
                                       )
                   )
     )
testing(L)
*/
.

役に立ちましたか?

解決

書く:

リストRLは非常に大きくてもよいので、新しいメモリを使用したくない(コピー RLの一部)。これはそれをするための方法ですか?

かなり(私があなたのコードで一目から言うことができる限り)。

RとのすべてのExchangeは、SEXPがポインタを表しているP型を使用します - これらはではない浅いプロキシオブジェクトです。Rオブジェクトメモリを使用/再利用します。

SO Profile / Memory-Profileこれは、N= 10とN= 1E5の場合も同様に動作する必要があります。しかし、証明はプディングにあります...

他のヒント

いくつかのこと:

  • ループテストn2< as<int>(L2["stages"])はどちらも読みにくい 各反復で計算されるのは非効率的です。あなたがすべき 間違いなく一度だけそれをしてください。

  • あなたのas< vector<string> >のすべては深いコピーを作成し、そうではありません Rの文字列キャッシュを利用してください。Aを使えませんか 代わりにCharacterVector

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top