Skip to content

Optimize SpSubview::operator%=(Base) and SpSubview::operator/=(Base).

I came across some inefficiencies when I wrote code like this:

#include <armadillo>

int main()
{
  arma::sp_mat x;
  x.sprandu(10000, 1000, 0.01);
  arma::sp_mat x2(x);
  arma::vec b(10000, arma::fill::randu);

  c.tic();
  for (size_t i = 0; i < x.n_cols; ++i)
    x.col(i) %= b;
  time = c.toc();
  std::cout << "operator%=(vec): " << time << "s.\n";

  x = x2;
  c.tic();
  for (size_t i = 0; i < x.n_cols; ++i)
    x.col(i) /= b;
  time = c.toc();
  std::cout << "operator/=(vec): " << time << "s.\n";
}

This gave

operator%=(vec): 0.289366s.
operator/=(vec): 0.425331s.

(That got really bad when I originally did it for a larger matrix.) I discovered that the implementation was creating a new sparse object that was the extracted subview, computing the % or / operator on that new sparse object, and then reinserting the result.

But, we can just use iterators instead. With the changes in this MR the results of the test program above are:

operator%=(vec): 0.000422s.
operator/=(vec): 0.000431s.

Merge request reports