滚动均值(C++)
向量化的滚动均值函数 rollmean3() 性能不错,但可读性很差。很难一眼看出这段代码是在计算滚动均值,这会让函数更难调试和维护。
第二个版本 rollmean2() 较慢,但更易读。如果我们把它翻译成 C++,有望同时获得良好的可读性和更快的性能。
rollmean2() 已在您的工作区中定义;您可以打印其定义来回顾它的工作方式。现在请把 rollmean2() 翻译为 C++,并将其命名为 rollmean4()。
本练习是课程的一部分
用 Rcpp 优化 R 代码
练习说明
- 将
res设为一个长度为n的NumericVector,其取值由NumericVector的get_na()方法给出。 - 将
total计算为x的前window个值之和。 - 在索引
window - 1处计算均值,即用总和除以窗口的宽度。 - 在第二个循环中,通过减去
x的第i - window个元素并加上第i个元素来更新总和。
交互式实操练习
通过完成这段示例代码来试试这个练习。
#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
)
*/