Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+的备选方案/建议+;虚函数多态性 我有一个程序,主要计算C++中非常大的向量的滚动平均和其他滚动统计。对于大小为N的向量,我想得到另一个大小为N的向量,元素k包含从0到k的滚动统计信息。下面我将使用滚动平均值进行说明_C++_Polymorphism - Fatal编程技术网

C+的备选方案/建议+;虚函数多态性 我有一个程序,主要计算C++中非常大的向量的滚动平均和其他滚动统计。对于大小为N的向量,我想得到另一个大小为N的向量,元素k包含从0到k的滚动统计信息。下面我将使用滚动平均值进行说明

C+的备选方案/建议+;虚函数多态性 我有一个程序,主要计算C++中非常大的向量的滚动平均和其他滚动统计。对于大小为N的向量,我想得到另一个大小为N的向量,元素k包含从0到k的滚动统计信息。下面我将使用滚动平均值进行说明,c++,polymorphism,C++,Polymorphism,程序有一个对象,该对象具有基于新值和以前的统计值更新滚动统计的功能。例如: inline float update(const float x) { _n++; _mean += (x - _mean)/_n; return _mean; } 现在我想支持其他统计计算,比如滚动标准差,计划是添加一个纯虚拟类作为基类,使用纯虚拟步长函数,创建不同统计类型对应的不同子类 我的问题是:因为step函数将是函数的主要部分,并且将被执行数十亿次,所以我是否希望通过从内联函数切换到

程序有一个对象,该对象具有基于新值和以前的统计值更新滚动统计的功能。例如:

inline float update(const float x) {
    _n++;
    _mean += (x - _mean)/_n;
    return _mean;
}
现在我想支持其他统计计算,比如滚动标准差,计划是添加一个纯虚拟类作为基类,使用纯虚拟步长函数,创建不同统计类型对应的不同子类


我的问题是:因为step函数将是函数的主要部分,并且将被执行数十亿次,所以我是否希望通过从内联函数切换到虚拟函数来降低速度?对于我想做的事情,还有其他更有效的选择吗?或者我没有使用正确的设计模式,还有其他更好的方法吗?

使用多态性通常是一个非常好的策略。这是一种经过验证和时间考验的方法,可用于构建正确且可维护的软件。vtable问题很少是影响性能的因素。一些有趣的文章和关于vtable的大量优化

还有其他一些好主意。例如,查看下面的示例。在创建处理程序对象时,您可以使用它来选择所选函数,可能是通过模板或作为ctor的参数。由于该策略在施工时选择一次,因此不会产生任何可变的惩罚

另一个相关的想法是将lambda函数与一些std::算法结合使用。自C++11以来,这种模式变得非常普遍。lambda用于代替多态性。下面是一个简单的例子,可以为您的项目提供一些想法

#include <iostream>
#include <vector>
#include <algorithm>

int main(int argc, char*argv[])
{
   std::vector<size_t> input = {2,4,6};
   std::vector<size_t> output;

   auto const operation = std::stoi(argv[1]);

   // transform the input vector to the output vector with algorithm selection
   switch(operation)
   {
     // just copy it
     case 1:  
     {
       std::for_each(input.begin() ,input.end(), [&](size_t element){
          output.push_back(element);
       });
       break;
     }

     // divide it by 2
     case 2:  
     {
       std::for_each(input.begin() ,input.end(), [&](size_t element){
          output.push_back(element/2);
       });
       break;
     }
   }

   for(auto const & element:output)
     std::cout << element << std::endl;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
向量输入={2,4,6};
std::矢量输出;
自动常量操作=std::stoi(argv[1]);
//使用算法选择将输入向量转换为输出向量
开关(操作)
{
//复制它就行了
案例1:
{
std::for_each(input.begin()、input.end()、[&](size_t元素){
输出。推回(元件);
});
打破
}
//除以2
案例2:
{
std::for_each(input.begin()、input.end()、[&](size_t元素){
输出。推回(元件/2);
});
打破
}
}
用于(自动常量和元素:输出)

std::cout使用多态性通常是一种非常好的策略。它是一种经过验证和时间考验的方法,可以构建正确的和可维护的软件。vtable问题很少是性能的一个因素。一些有趣的文章和关于vtable的大量优化

还有其他一些好主意。请查看示例。在创建处理程序对象时,您可以使用它来选择所选函数,可能是通过模板或作为ctor的参数。由于策略在构造时选择一次,因此不会产生vtable惩罚

另一个相关的想法是将lambda函数与一些std::算法结合使用。自C++11以来,这种模式变得非常普遍。lambda被用来代替多态性。下面是一个简单的示例,可以为您的项目提供一些想法

#include <iostream>
#include <vector>
#include <algorithm>

int main(int argc, char*argv[])
{
   std::vector<size_t> input = {2,4,6};
   std::vector<size_t> output;

   auto const operation = std::stoi(argv[1]);

   // transform the input vector to the output vector with algorithm selection
   switch(operation)
   {
     // just copy it
     case 1:  
     {
       std::for_each(input.begin() ,input.end(), [&](size_t element){
          output.push_back(element);
       });
       break;
     }

     // divide it by 2
     case 2:  
     {
       std::for_each(input.begin() ,input.end(), [&](size_t element){
          output.push_back(element/2);
       });
       break;
     }
   }

   for(auto const & element:output)
     std::cout << element << std::endl;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
向量输入={2,4,6};
std::矢量输出;
自动常量操作=std::stoi(argv[1]);
//使用算法选择将输入向量转换为输出向量
开关(操作)
{
//复制它就行了
案例1:
{
std::for_each(input.begin()、input.end()、[&](size_t元素){
输出。推回(元件);
});
打破
}
//除以2
案例2:
{
std::for_each(input.begin()、input.end()、[&](size_t元素){
输出。推回(元件/2);
});
打破
}
}
用于(自动常量和元素:输出)

据我所知,您可以使用模板,类似于

template <typename Range, typename F>
auto f(const Range& r, F&& f)
{
    std::vector<std::decay_t<decltype(f(*r.begin()))>> result;

    result.reserve(r.size());
    for (const auto& e : v) {
        result.push_back(f(e));
    }
    return result;
}


class MeanCalculator
{
public:
    float operator()(float x) const {
        n++;
        mean += (x - mean) / n;
        return mean;
    }
private:
    std::size_t n = 0;
    float mean = 0.0f;
};

class VarianceCalculator
{
public:
    float operator()(float x) const {
        n++;
        // ...
    }
private:
    std::size_t n = 0;
    //...
};
模板
自动f(常数范围和r、f和f)
{
std::向量结果;
结果:保留(r.size());
用于(常数自动和e:v){
结果:推回(f(e));
}
返回结果;
}
类均值计算器
{
公众:
浮点运算符()(浮点x)常量{
n++;
平均值+=(x-平均值)/n;
回归均值;
}
私人:
标准:尺寸n=0;
浮动平均值=0.0f;
};
类变量计算器
{
公众:
浮点运算符()(浮点x)常量{
n++;
// ...
}
私人:
标准:尺寸n=0;
//...
};
然后

std::vector<float> numbers = /*...*/;
auto means = f(numbers, MeanCalculator{});
auto variances = f(numbers, VarianceCalculator{});
std::向量数=/*…*/;
自动平均数=f(数字,平均计算器{});
自动方差=f(数字,方差计算器{});

注意:
std::transform
不能使用,因为它不能保证按顺序应用
f

据我所知,您可以使用模板,类似于

template <typename Range, typename F>
auto f(const Range& r, F&& f)
{
    std::vector<std::decay_t<decltype(f(*r.begin()))>> result;

    result.reserve(r.size());
    for (const auto& e : v) {
        result.push_back(f(e));
    }
    return result;
}


class MeanCalculator
{
public:
    float operator()(float x) const {
        n++;
        mean += (x - mean) / n;
        return mean;
    }
private:
    std::size_t n = 0;
    float mean = 0.0f;
};

class VarianceCalculator
{
public:
    float operator()(float x) const {
        n++;
        // ...
    }
private:
    std::size_t n = 0;
    //...
};
模板
自动f(常数范围和r、f和f)
{
std::向量结果;
结果:保留(r.size());
用于(常数自动和e:v){
结果:推回(f(e));
}
返回结果;
}
类均值计算器
{
公众:
浮点运算符()(浮点x)常量{
n++;
平均值+=(x-平均值)/n;
回归均值;
}
私人:
标准:尺寸n=0;
浮动平均值=0.0f;
};
类变量计算器
{
公众:
浮点运算符()(浮点x)常量{
n++;
// ...
}
私人:
标准:尺寸n=0;
//...
};
然后

std::vector<float> numbers = /*...*/;
auto means = f(numbers, MeanCalculator{});
auto variances = f(numbers, VarianceCalculator{});
std::向量数=/*…*/;
自动平均数=f(数字,平均计算器{});
自动方差=f(数字,方差计算器{});
注: