Получить параметры из списка с помощью Rcpp
Вопрос
Впервые в Rcpp. Я тестирую, как получить и использовать вложенный список из R с известной структурой без повторного копирования частей списка.Небольшой пример кода (со встроенным кодом R), похоже, работает (для отладки используется cout).
Список rL, полученный из R, может быть очень большим, поэтому я не хочу перераспределять память (копировать части rL).Копирует ли текущий код части rL?
Лучший Ларс
#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 использует SEXP
типы, где P
означает указатель — это мелкие прокси-объекты, которые будут не копироваться.Он использует/повторно использует память объекта R.
Итак, если вы профилируете/профилируете память, он должен вести себя одинаково для N=10 и N=1e5.Но доказательство - в пудинге...
Другие советы
Несколько вещей:
- .
-
Тест петли GeneacodicetacodcodCode - это сложно читать и неэффективно, как он рассчитывается на каждой итерации.Вам следует Определенно сделайте это только один раз.
-
Все ваши генеракодицетагкод создают глубокие копии и не Воспользуйтесь преимуществами строки R.Разве вы не можете использовать Вместо того, чтобы
n2< as<int>(L2["stages"])
?