C++:表达式模板中循环的性能
我在类似向量的类中使用表达式模板进行变换,例如移动平均。这里,与标准算术运算不同,运算符[]size_t i不单独访问元素i,而是需要评估整个循环,例如向量v的移动平均值 在函数中,可以选择存储结果:C++:表达式模板中循环的性能,c++,expression-templates,C++,Expression Templates,我在类似向量的类中使用表达式模板进行变换,例如移动平均。这里,与标准算术运算不同,运算符[]size_t i不单独访问元素i,而是需要评估整个循环,例如向量v的移动平均值 在函数中,可以选择存储结果: template<typename VectorType> auto MovingAverage(VectorType const& vector, int period = 10) -> VecMovingAverage<VectorType> {
template<typename VectorType>
auto MovingAverage(VectorType const& vector, int period = 10) -> VecMovingAverage<VectorType>
{
static const bool Store=true;
return VecMovingAverage<VectorType, Store>(vector, period);
}
这可以扩展,以便存储仅应用于多个应用程序等。如果您想要更可靠的优化,请使用std::acculate。谢谢,但我认为只有在容器已填充时才可能使用std::acculate,即在上面的代码中,仅适用于Vec类。对于VecTransform类,没有可迭代的容器,只有一个特殊的运算符[]。可复制的示例将有所帮助,而不是伪代码片段。
#include <vector>
template <typename E>
struct VecExpression
{
double operator[](int i) const { return static_cast<E const&>(*this)[i]; }
};
struct Vec : public VecExpression<Vec>
{
Vec(size_t N) : data(N) {}
double operator[](int i) const { return data[i]; }
double& operator[](int i) { return data[i]; }
std::vector<double> data;
};
template <typename VectorType>
struct VecMovingAverage : public VecExpression<VecMovingAverage<VectorType> >
{
VecMovingAverage(VectorType const& _vector, int _period) : vector(_vector), period(_period) {}
double operator[](int i) const
{
int s = std::max(i - period + 1, 0);
double ad = 0.0;
for (int j = s; j <= i; ++j)
ad += vector[j];
return ad / (i - s + 1);
}
VectorType const& vector;
int period;
};
template<typename VectorType>
auto MovingAverage(VectorType const& vector, int period = 10) -> VecMovingAverage<VectorType>
{
return VecMovingAverage<VectorType>(vector, period);
}
Vec vec(100);
auto tripleMA= MovingAverage(MovingAverage(MovingAverage(vec,20),20),20);
std::cout << tripleMA[40] << std::endl;
template <typename VectorType, bool Store>
struct VecMovingAverage : public VecExpression<VecMovingAverage<VectorType, Store> >
{
VecMovingAverage(VectorType const& _vector, int _period) : vector(_vector), period(_period) {}
double operator[](int i) const
{
if(Store && i<data.size())
{
return data[i];
}
else
{
int s = std::max(i - period + 1, 0);
double ad = 0.0;
for (int j = s; j <= i; ++j)
ad += vector[j];
ad /= (i - s + 1)
if(Store)
{
data.resize(i+1);
data[i]=ad;
}
return ad;
}
}
VectorType const& vector;
int period;
};
template<typename VectorType>
auto MovingAverage(VectorType const& vector, int period = 10) -> VecMovingAverage<VectorType>
{
static const bool Store=true;
return VecMovingAverage<VectorType, Store>(vector, period);
}