Wektory STL
Standardowa biblioteka szablonów (STL) to biblioteka C++ zawierająca elastyczne algorytmy i struktury danych. Na przykład wektor typu double z STL jest odpowiednikiem NumericVector z Rcpp w „natywnym C++". Poniższy kod tworzy standardowy wektor liczb zmiennoprzecinkowych o nazwie x zawierający dziesięć elementów.
std::vector<double> x(10);
Na ogół lepiej trzymać się typów wektorów z Rcpp – dają dostęp do wielu wygodnych metod działających jak ich odpowiedniki w R, m.in. mean(), round() i abs(). Wektory STL mają jednak tę zaletę, że mogą dynamicznie zmieniać rozmiar bez kopiowania danych przy każdej zmianie. Dzięki temu można pisać prostszy kod – podobny do funkcji „bad" z poprzedniego ćwiczenia – zachowując przy tym wydajność funkcji „good".
To ćwiczenie jest częścią kursu
Optymalizacja kodu R za pomocą Rcpp
Instrukcje do ćwiczenia
- Uzupełnij definicję funkcji
select_positive_values_std()– funkcji opartej na wektorze STL, która wybiera liczby dodatnie.- Ustaw typ zwracany funkcji na standardowy wektor liczb zmiennoprzecinkowych, używając
std::vector<double>. - Zdefiniuj standardowy wektor liczb zmiennoprzecinkowych
positive_xo rozmiarze0. - Wewnątrz bloku
ifw pętliforużyj metodypush_back()napositive_x, aby dołączyć i-ty element wektorax.
- Ustaw typ zwracany funkcji na standardowy wektor liczb zmiennoprzecinkowych, używając
- Funkcja
good_select_positive_values_cpp()z poprzedniego ćwiczenia jest dostępna w twoim środowisku pracy – możesz jej użyć do porównania. Sprawdź wyniki w konsoli, aby zobaczyć różnicę w szybkości działania obu funkcji.
Interaktywne ćwiczenie praktyczne
Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.
#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)
)
*/