STL-vectors
De standard template library (stl) is een C++-bibliotheek met flexibele algoritmen en datastructuren. Zo is de double vector uit de stl het "native C++"-equivalent van Rcpp’s NumericVector. De volgende code maakt een standaard double vector x met tien elementen.
std::vector<double> x(10);
Meestal is het handiger om Rcpp-vectortypen te gebruiken, omdat je dan veel handige methoden hebt die werken zoals in R, zoals mean(), round() en abs(). STL-vectors hebben echter het voordeel dat ze hun grootte dynamisch kunnen aanpassen zonder elke keer de data te kopiëren. Daardoor kun je eenvoudigere code schrijven, zoals de "slechte" functie uit de vorige oefening, terwijl je toch de prestaties van de "goede" code behoudt.
Deze oefening maakt deel uit van de cursus
R-code optimaliseren met Rcpp
Oefeninstructies
- Maak de definitie af van
select_positive_values_std(), een op stl-vectors gebaseerde functie om positieve getallen te selecteren.- Stel het retourtype van de functie in op een standaard double vector met
std::vector<double>. - Definieer een standaard double vector,
positive_x, met grootte0. - Gebruik binnen het
if-blok in defor-lus depush_back()vanpositive_xom het i-de element vanxtoe te voegen.
- Stel het retourtype van de functie in op een standaard double vector met
good_select_positive_values_cpp()uit de vorige oefening staat in je workspace ter vergelijking. Bekijk de console-uitvoer om de relatieve snelheid van de twee functies te zien.
Praktische interactieve oefening
Probeer deze oefening eens door deze voorbeeldcode in te vullen.
#include
using namespace Rcpp;
// Set the return type to a standard double vector
// [[Rcpp::export]]
___ select_positive_values_std(NumericVector x) {
int n = x.size();
// Create positive_x, a standard double vector
___;
for(int i = 0; i < n; i++) {
if(x[i] > 0) {
// Append the ith element of x to positive_x
___;
}
}
return positive_x;
}
/*** R
set.seed(42)
x <- rnorm(1e6)
# Does it give the same answer as R?
all.equal(select_positive_values_std(x), x[x > 0])
# Which is faster?
microbenchmark(
good_cpp = good_select_positive_values_cpp(x),
std = select_positive_values_std(x)
)
*/