Rolling mean (di C++)
Fungsi rolling mean tervektorisasi, rollmean3(), memiliki kinerja yang baik tetapi keterbacaan yang sangat buruk. Sulit sekali melihat bahwa kode ini menghitung rolling mean, sehingga fungsi lebih sulit di-debug dan dipelihara.
Versi kedua, rollmean2(), lebih lambat tetapi lebih mudah dibaca. Jika kita terjemahkan ke C++, semoga kita mendapatkan keterbacaan yang mudah dan kinerja yang cepat.
rollmean2() sudah didefinisikan di workspace Anda; Anda dapat mencetak definisinya untuk mengingat cara kerjanya. Sekarang Anda akan menerjemahkan rollmean2() ke C++ dan menamainya rollmean4().
Latihan ini adalah bagian dari kursus
Mengoptimalkan Kode R dengan Rcpp
Petunjuk latihan
- Atur
ressebagaiNumericVectordengan panjangndan nilai yang diberikan oleh metodeget_na()milikNumericVector. - Hitung
totalsebagaiwindownilai pertama darix. - Hitung mean pada
window - 1sebagai total dibagi lebar jendela. - Pada loop kedua, perbarui total dengan mengurangkan elemen ke-
i - windowdarixdan menambahkan elemen ke-idarix.
Latihan interaktif praktis
Cobalah latihan ini dengan menyelesaikan kode contoh berikut.
#include
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector rollmean4(NumericVector x, int window) {
int n = x.size();
// Set res as a NumericVector of NAs with length n
NumericVector res(___, ___::___());
// Sum the first window worth of values of x
double total = 0.0;
for(int i = 0; i < window; i++) {
total += ___;
}
// Treat the first case seperately
res[window - 1] = ___ / window;
// Iteratively update the total and recalculate the mean
for(int i = window; i < n; i++) {
// Remove the (i - window)th case, and add the ith case
total += - ___ + ___;
// Calculate the mean at the ith position
res[i] = total / window;
}
return res;
}
/*** R
# Compare rollmean2, rollmean3 and rollmean4
set.seed(42)
x <- rnorm(1e4)
microbenchmark(
rollmean2(x, 4),
rollmean3(x, 4),
rollmean4(x, 4),
times = 5
)
*/