<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hello Romain,<div>maybe then another function, like force_create() could be available? Or some checks for equal number of elements in each vector.</div><div>One of the main Rcpp advantages to the user is its flexibility and speed, compared to the plain R code.</div><div>I am not sure at this point what solution would be the best, but having fast methods in Rcpp would be really great.</div><div>Should I wait then before submitting the pull request?</div><div>Dmitry</div><div><br></div><div><div><div>On Jun 7, 2014, at 7:21 AM, Romain François <<a href="mailto:romain@r-enthusiasts.com">romain@r-enthusiasts.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>Le 7 juin 2014 à 03:27, Dmitry Nesterov <<a href="mailto:dmitry.nesterov@gmail.com">dmitry.nesterov@gmail.com</a>> a écrit :<br><br><blockquote type="cite">Hello,<br>Here I report the slowness in creation of Rcpp DataFrame objects and proposed change to speed it up.<br>For system information, here is output from sessionInfo():<br>R version 3.1.0 (2014-04-10)<br>Platform: x86_64-apple-darwin13.1.0 (64-bit)<br>...<br>other attached packages:<br>[1] microbenchmark_1.3-0 Rcpp_0.11.1         <br><br>I am using Rcpp package to port my old functions written with R's C interface to a more convenient style of Rcpp.<br>While writing code that creates data.frame’s, I noticed that the Rcpp-based code was running quite a bit slower (using microbenchmark package) than my old implementation. The difference was approximately 40(!) times slower for data frame 50x2 (row x col)<br><br>I have narrowed the speed difference down to the following call:<br><br>  return Rcpp::DataFrame::create(Rcpp::Named(“xdata”)=x,<br>                                 Rcpp::Named(“ydata”)=y);<br><br>Where x and y are Rcpp::NumericVector objects.<br>By debugging through the code and Rcpp, I noticed that during the creation Rcpp uses “as.data.frame” conversion on the vector list that contained x, y vectors and their names “xdata” and “ydata”, while this step was not necessary in my previous code using C interface.<br></blockquote><br>Well, how then do you guarantee that the data frame is not corrupt ?<br><br>Consider this code:<span class="Apple-converted-space"> </span><br><br>#include <Rcpp.h><br>using namespace Rcpp ;<br><br>// [[Rcpp::export]]<br>DataFrame test(){<br> NumericVector x = NumericVector::create( 1, 2, 3, 4 ) ;<br> NumericVector y = NumericVector::create( 1, 2 ) ;<br> return DataFrame::create(_["x"] = x, _["y"] = y ) ;<br>}<br><br>The benefit of calling as.data.frame is that it would handle recycling y correctly.<span class="Apple-converted-space"> </span><br><br>Just setting the class attribute to "data.frame" by brute force would make a corrupt data frame. Perhaps you can get your suggestion approved on the basis of being consistent with other ways to get corrupt data frames in Rcpp.<span class="Apple-converted-space"> </span><br><a href="https://github.com/RcppCore/Rcpp/issues/144">https://github.com/RcppCore/Rcpp/issues/144</a><span class="Apple-converted-space"> </span><br><br>The basic idea is valid, but this would need more work and understanding of the conceptual requirements of a data frame.<span class="Apple-converted-space"> </span><br><br>Romain<br><br><br><blockquote type="cite">In Rcpp/DataFrame.h:87<br>     static DataFrame_Impl from_list( Parent obj ){<br>This in turn calls on line 104:<br>              return DataFrame_Impl(obj) ;<br>and which ultimately calls on line 78:<br>      void set__(SEXP x){<br>          if( ::Rf_inherits( x, "data.frame" )){<br>              Parent::set__( x ) ;<br>          } else{<br>              SEXP y = internal::convert_using_rfunction( x, "as.data.frame" ) ;<br>              Parent::set__( y ) ;<br>          }<br>      }<br>Since the DataFrame::create() function has not set a class attribute to “data.frame” by far, the conversion “as.data.frame” takes place and slows down the creation of the final object.<br>I propose to make change on line 103 to set class attribute to “data.frame”, so no further conversion will take place:<br>          if( use_default_strings_as_factors ) {<br>              Rf_setAttrib(obj, R_ClassSymbol, Rf_mkString("data.frame"));<br>              return DataFrame_Impl(obj) ;<br>          }<br><br>I tested it and it brought the speed of execution of the function to about the same as it was before with plain C API.<br>Please let me know if it makes sense or maybe I should use DataFrame::create() function differently.<br><br>Best,<br>Dmitry<br><br>_______________________________________________<br>Rcpp-devel mailing list<br><a href="mailto:Rcpp-devel@lists.r-forge.r-project.org">Rcpp-devel@lists.r-forge.r-project.org</a><br><a href="https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel">https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel</a></blockquote></div></blockquote></div><br></div></body></html>