1

I am using Rcpp for analysis of XTS data and get its time index by using the following rcpp code:

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

// [[Rcpp::export]]
DatetimeVector xtsIndex(NumericMatrix X)
{
  DatetimeVector v(NumericVector(X.attr("index")));
  return v;
}

DatetimeVector tmpindexDaily = xtsIndex(askDailymat);  // Get xts index to Rcpp vector

It turns out this conversion takes 2 ms to execute on a certain set of data were I only need time index, without this code, it takes less that 100 microseconds. Is there any way to better optimize the conversion or to avoid it entirely.

Alvin
  • 351
  • 3
  • 13
  • Can you add `dput(askDailyMat)` to your question please? – nrussell Apr 20 '15 at 14:50
  • @nrussell did you mean to call dput() r function in Rcpp code? I think it will slow down the calculation if calling any R function. I got the original codes from Dirk Eddelbuettel's post at http://gallery.rcpp.org/articles/getting-attributes-for-xts-example/ – Alvin Apr 20 '15 at 14:58
  • No, I just needed an example object to test your function on. Thank you. What's going on with this freestanding line: `DatetimeVector tmpindexDaily = xtsIndex(askDailymat);` - is that part of a larger piece of code, or just something you included accidentally? – nrussell Apr 20 '15 at 15:21
  • @nrussell The line DatetimeVector tmpindexDaily = xtsIndex(askDailymat) is used to call this xtsIndex function, it is the part of a larger piece of code, and the input askDailymat is xts data type, which is like this (time index and price level): 2010-01-04 00:02:20 -1044.0 2010-01-04 00:02:21 -1045.0 2010-01-04 00:02:26 -1045.0 2010-01-04 00:18:16 -1047.5 2010-01-04 00:42:52 -1047.5 2010-01-04 01:07:25 -1046.5 2010-01-04 01:25:03 -1047.5 2010-01-04 01:25:09 -1046.5 2010-01-04 01:54:20 -1047.5 2010-01-04 02:01:28 -1046.5 – Alvin Apr 20 '15 at 15:29
  • 2
    I presume you are the same Alvin as the one who asked [this question about Rcpp and the xts interface](http://stackoverflow.com/questions/29706386/rcpp-debug-fatal-error-datetime-h-no-such-file-or-directory-xtsapi-h-no-su). Why do you keep creating new accounts? – Dirk Eddelbuettel Apr 20 '15 at 15:33
  • @DirkEddelbuettel Yes, thanks Dirk, for some reason stackoverflow blocks me to post questions and get a new account – Alvin Apr 20 '15 at 15:38
  • @Alvin I'm not sure there *is* anything to optimize here, aside from using `const Rcpp::NumericMatrix& X` instead of `Rcpp::NumericMatrix X` as your function parameter, which should get you a very slight performance increase. Interestingly, making the conversion `v(NumericVector(X.attr("index"))); ...` was faster than just directly calling `return X.attr("index");` on my machine, which I am a little curious about. – nrussell Apr 20 '15 at 15:45
  • @nrussell Thanks for the note, and I just tried yours, which did get a slight performance increase. I was thinking to quote askDailymat as a matrix and using ---- #include std::vector indexDaily = Rcpp::as< std::vector > (askDailymat), which doesn't work... – Alvin Apr 20 '15 at 16:06
  • 2
    Rcpp's DatetimeVector class is somewhat of an outlier in the Rcpp api. It has never been correctly designed. The way the class is currently organized leads to many many data copies. – Romain Francois Apr 21 '15 at 11:55
  • 1
    The reason I pull out the time index info is that I try to get the trading time distribution. A feasible way to speedup is to only convert the xts data rows when there are trading signals since the main reason slows down the `DatetimeVector tmpindexDaily = xtsIndex(askDailymat)` is because `NumericMatrix askDailymat` that stores xts data is large. I try to create a submatrix `NumericMatrix tmp = askDailymat(Range(kk,kk), Range(0,1))` to contain the traded xts data kk row, but the time index info is lost. So is there any way to pull out part of `askDailymat` and remain the xts type? – Alvin Apr 21 '15 at 14:33

1 Answers1

4

You may be better off just using a NumericVector with a proper class attribute. Here is a quick one-off function I used a few weeks ago in another project:

Rcpp::NumericVector createPOSIXtVector(const std::vector<double> & ticks, 
                                       const std::string tz) {
    Rcpp::NumericVector pt(ticks.begin(), ticks.end());
    pt.attr("class") = Rcpp::CharacterVector::create("POSIXct", "POSIXt");
    pt.attr("tzone") = tz;
    return pt;
}

You can start similarly from other containers, matrix colums, vectors, ... that can hold double values and use the fact that time (POSIXct) time is really a fractional double since the epoch. Here we got a std::vector<double> from another API so the conversion is pretty cheap.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725