1. Učit se
  2. /
  3. Kurzy
  4. /
  5. Optimizing R Code with Rcpp

Connected

cvičení

Neměň velikost Rcpp vektorů

Třídy Rcpp vektorů jsou navrženy jako velmi tenké obálky kolem R vektorů. Z toho plyne výkonnostní důsledek: zvětšení nebo zmenšení vektoru znamená vytvoření nového vektoru správné velikosti a zkopírování příslušných dat. Jde o velmi pomalou operaci, které je lepší se vyhnout.

Kdykoli je to možné, je vhodné kód strukturovat tak, aby se nejprve vypočítala výsledná velikost vektoru a teprve pak se alokoval vektor s touto velikostí.

Podívejme se na příklad, který vybere kladné hodnoty z vektoru — to odpovídá výrazu x[x > 0] v R. Protože dopředu nevíme, kolik kladných čísel bude, může být lákavé začít s vektorem nulové délky a pokaždé, když takové číslo najdeme, přidat ho na konec. K tomu slouží funkce push_back().

NumericVector bad_select_positive_values_cpp(NumericVector x) {
  NumericVector positive_x(0);
  for(int i = 0; i < x.size(); i++) {
    if(x[i] > 0) {
      positive_x.push_back(x[i]);
    }
  }
  return positive_x;
}

Tato funkce bude bohužel pomalá, protože opakovaně vytváří nové vektory a kopíruje data. Zkus to udělat lépe!

Pokyny

100 XP
  • Dokonči definici efektivnější funkce good_select_positive_values_cpp(), která vybere kladná čísla.
    • V prvním cyklu for zkontroluj, jestli je i-tý prvek vektoru x větší než nula — pokud ano, přičti jedničku k n_positive_elements.
    • Po tomto cyklu alokuj numerický vektor positive_x o velikosti n_positive_elements.
    • Ve druhém cyklu for znovu zkontroluj, jestli je i-tý prvek vektoru x větší než nula.
    • Pokud ano, nastav j-tý prvek vektoru positive_x na i-tý prvek vektoru x a přičti jedničku k j.
  • Pro srovnání máš v pracovním prostředí k dispozici funkci bad_select_positive_values_cpp(). Prohlédni si výstup konzole a zjisti, jaký je mezi nimi rozdíl v době běhu.