STL vektory
Standardní knihovna šablon (STL) je knihovna jazyka C++ obsahující flexibilní algoritmy a datové struktury. Například typ double vektoru ze STL je jakoby „nativní C++" ekvivalent Rcpp třídy NumericVector. Následující kód vytvoří standardní double vektor s názvem x obsahující deset prvků.
std::vector<double> x(10);
Většinou je výhodnější držet se Rcpp vektorových typů, protože ti dávají přístup k mnoha praktickým metodám, které fungují podobně jako jejich protějšky v R – včetně mean(), round() a abs(). STL vektory mají ale jednu výhodu: mohou dynamicky měnit svou velikost, aniž by při každé změně docházelo ke kopírování dat. To nám umožňuje psát jednodušší kód – podobně jako funkce „bad" z předchozího cvičení – a přitom si zachovat výkon funkce „good".
Toto cvičení je součástí kurzu
Optimizing R Code with Rcpp
Pokyny k cvičení
- Dokonči definici funkce
select_positive_values_std(), která využívá STL vektory k výběru kladných čísel.- Nastav návratový typ funkce na standardní double vektor pomocí
std::vector<double>. - Definuj standardní double vektor
positive_xs velikostí0. - Uvnitř bloku
ifve smyčceforpoužij metodupush_back()vektorupositive_xk přidání i-tého prvku vektorux.
- Nastav návratový typ funkce na standardní double vektor pomocí
- Funkce
good_select_positive_values_cpp()z předchozího cvičení je dostupná ve tvém pracovním prostoru pro srovnání. Prohlédni si výstup v konzoli a porovnej relativní rychlosti obou funkcí.
Interaktivní cvičení na vyzkoušení si v praxi
Vyzkoušejte si toto cvičení dokončením tohoto ukázkového kódu.
#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)
)
*/