STL-Vektoren
Die Standard Template Library (stl) ist eine C++-Bibliothek mit flexiblen Algorithmen und Datenstrukturen. Der Double-Vektor aus der stl ist zum Beispiel das „native C++“-Äquivalent zu Rcpps NumericVector. Der folgende Code erzeugt einen Standard-Double-Vektor namens x mit zehn Elementen.
std::vector<double> x(10);
In der Regel ist es sinnvoller, bei Rcpp-Vektortypen zu bleiben, weil du damit viele Komfortmethoden bekommst, die wie ihre R-Pendants funktionieren, darunter mean(), round() und abs(). Die stl-Vektoren haben jedoch den Vorteil, dass sie ihre Größe dynamisch ändern können, ohne jedes Mal die Daten kopieren zu müssen. So können wir einfacheren Code schreiben, etwa wie die „schlechte“ Funktion aus der vorherigen Übung, und trotzdem die Performance des „guten“ Codes beibehalten.
Diese Übung ist Teil des Kurses
R-Code mit Rcpp optimieren
Anleitung zur Übung
- Vervollständige die Definition von
select_positive_values_std(), einer auf stl-Vektoren basierenden Funktion, die positive Zahlen auswählt.- Setze den Rückgabetyp der Funktion auf einen Standard-Double-Vektor mit
std::vector<double>. - Definiere einen Standard-Double-Vektor
positive_xmit der Größe0. - Nutze innerhalb des
if-Blocks in derfor-Schleife die Methodepush_back()vonpositive_x, um das i-te Element vonxanzuhängen.
- Setze den Rückgabetyp der Funktion auf einen Standard-Double-Vektor mit
good_select_positive_values_cpp()aus der vorherigen Übung steht dir zum Vergleich in deinem Workspace zur Verfügung. Sieh dir die Konsolenausgabe an, um die relativen Geschwindigkeiten der beiden Funktionen zu vergleichen.
Interaktive Übung
Vervollständige den Beispielcode, um diese Übung erfolgreich abzuschließen.
#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)
)
*/