C++:表达式模板中循环的性能

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> {

我在类似向量的类中使用表达式模板进行变换,例如移动平均。这里,与标准算术运算不同,运算符[]size_t i不单独访问元素i,而是需要评估整个循环,例如向量v的移动平均值

在函数中,可以选择存储结果:

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);
}