O RStudio trava com o RCpp com códigos reproduzíveis

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

> testDF
   V1 V2 V3 V4 V5 V6
1   1  5  4  1  3  2
2   2  1  5  4  1  3
3   2  2  1  5  4  1
4   3  2  2  1  5  4
5   1  3  2  2  1  5
6   4  1  3  2  2  1
7   1  5  4  1  3  2
8   2  1  5  4  1  3
9   2  2  1  5  4  1
10  3  2  2  1  5  4
11  1  3  2  2  1  5
12  4  1  3  2  2  1

> testSp<-c(1,1,1,2,2,2,3,4,4,3,3,5)

> split(testDF,testSp)     OR  > splitDataFrameCpp(testDF,testSp)     

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

1` V1 V2 V3 V4 V5 V6 1 1 5 4 1 3 2 2 2 1 5 4 1 3 3 2 2 1 5 4 1

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

2` V1 V2 V3 V4 V5 V6 4 3 2 2 1 5 4 5 1 3 2 2 1 5 6 4 1 3 2 2 1

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

3` V1 V2 V3 V4 V5 V6 7 1 5 4 1 3 2 10 3 2 2 1 5 4 11 1 3 2 2 1 5

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

4` V1 V2 V3 V4 V5 V6 8 2 1 5 4 1 3 9 2 2 1 5 4 1

@ user3759195 escreveu uma publicaçãohttps://stackoverflow.com/questions/24322356/rstudio-crashes-and-it-does-not-reproduce sobre o RStudio travar com o RCpp, mas não forneceu nenhum caso reproduzível. @KevinUshey mencionado nos comentários que temos quePROTECT awrap dentro do código.

Tomei a liberdade de postar duas alternativas parasplit.data.frame função escrita em RCpp:

* VERSÃO QUE NÃO CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;
  for (int i=0;i<int(yunq.size());i++) {
    NumericVector tmp1=wrap(z[yunq[i]]);   // *** DEFINING INSIDE LOOP ***
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    DataFrame tmp2(wrap(tmp1));   // *** DEFINING INSIDE LOOP ***
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }
  return wrap(z1);  
}

* VERSÃO QUE CAIXA O RSTUDIO *

//[[Rcpp::export]]
List splitDataFrameCpp(DataFrame x,NumericVector y) {
  int nRows=x.nrows();
  int nCols=x.size();

  std::map<double,vector<double> > z;
  for (int i=0;i<nCols;i++) {
    std::vector<double> tmp=Rcpp::as<std::vector<double> > (x[i]);
    for (int j=0;j<nRows;j++) {
      z[y[j]].push_back(tmp[j]);      
    }
  }

  std::vector<double> yunq=Rcpp::as<std::vector<double> > (sort_unique(y));
  std::map<double, DataFrame> z1;

  NumericVector tmp1;    // *** DEFINING OUTSIDE LOOP ***
  DataFrame tmp2;    // *** DEFINING OUTSIDE LOOP ***

  for (int i=0;i<int(yunq.size());i++) {
    tmp1=wrap(z[yunq[i]]);
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nCols,nCols);
    tmp2=wrap(tmp1);
    tmp2.attr("names")=x.attr("names");
    z1[yunq[i]]=tmp2;
  }    
  return wrap(z1);      
}

A principal diferença entre os dois códigos é que, em um casotmp1 etmp2 é definido dentro do loop e, no outro caso, fora do loop.

Alguém pode explicar por que o segundo loop trava (e o que pode ser alterado para NÃO causar o travamento do RStudio)? Ainda sou novato em C ++ e principalmente escrevi o RCpp observando exemplos no SO ou no site da galeria RCpp - então, gostaria de entender um pouco mais esse comportamento.

Além disso, como um benefício colateral, se alguém puder recomendar alterações para tornar o código mais rápido, isso será ótimo. O código que NÃO trava é atualmente cerca de 2x-3x vezes mais rápido que o de Rsplit.data.frame função baseada em alguns casos de teste que eu usei.

Exemplo de caso de teste:

5` V1 V2 V3 V4 V5 V6 12 4 1 3 2 2 1

omicrobenchmark resultado para este caso de teste:

> microbenchmark(t1<-split(testDF,testSp),t2<-splitDataFrameCpp(testDF,testSp))
Unit: microseconds
                                   expr     min      lq   median       uq      max neval
             t1 <- split(testDF, test2) 343.181 365.562 372.8760 387.9430 1027.786   100
 t2 <- splitDataFrameCpp(testDF, test2) 177.881 190.315 200.5545 208.4545  870.093   100

* EDIT *

Adicionado osessionInfo:

> sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] microbenchmark_1.3-0

loaded via a namespace (and not attached):
[1] Rcpp_0.11.1 tools_3.1.0

Além disso, o testDF foi criado como umnumeric em R, nãointeger.

questionAnswers(1)

yourAnswerToTheQuestion