r-lib / rray

Simple Arrays
https://rray.r-lib.org
GNU General Public License v3.0
130 stars 12 forks source link

`rray_yank()` / `rray_yank_assign()` are slow #220

Open DavisVaughan opened 5 years ago

DavisVaughan commented 5 years ago

A big part of this is because of unravel_indices(), which is much slower than I would have expected. Need to report upstream

DavisVaughan commented 5 years ago
template <typename T>
Rcpp::RObject rray__yank_impl2(const xt::rarray<T>& x, Rcpp::IntegerVector i) {

  using shape_type = typename xt::xarray<T>::shape_type;
  unsigned long n = i.size();
  int nn = i.size();
  shape_type shape = {n};
  xt::rarray<T> out(shape);

  auto data = x.data();

  for (int j = 0; j < nn; ++j) {
    out[j] = data[i[j]];
  }

  return Rcpp::as<Rcpp::RObject>(out);
}

// [[Rcpp::export(rng = false)]]
Rcpp::RObject rray__yank2(Rcpp::RObject x, Rcpp::IntegerVector i) {
  Rcpp::RObject out;
  DISPATCH_UNARY_ONE(out, rray__yank_impl2, x, i);

  rray__set_dim_names(out, rray__new_empty_dim_names(1));

  return out;
}

can potentially speed them up with a pure Rcpp version that just pulls out the i elements and returns that

juangomezduaso commented 5 years ago

Couldn't you just use base array [ and [<- functions ?

DavisVaughan commented 5 years ago

I was thinking about that, but we do want to avoid partial recycling

(its not out of the question, just need to be aware of base R behavior)

x <- array(1:5)
x[1:4] <- 1:2
x
#> [1] 1 2 1 2 5

library(rray)
x <- array(1:5)
x_rray <- as_rray(x)
x_rray[1:4] <- 1:2
#> Error: Cannot broadcast from (2) to (4) due to dimension 1.

Created on 2019-06-13 by the reprex package (v0.2.1)

juangomezduaso commented 5 years ago

Oh, yes. A length check is in order.