Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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++ 当我使用std::算法而不是普通循环时,为什么这段代码变得越来越慢?_C++_Algorithm_Optimization_Runtime - Fatal编程技术网

C++ 当我使用std::算法而不是普通循环时,为什么这段代码变得越来越慢?

C++ 当我使用std::算法而不是普通循环时,为什么这段代码变得越来越慢?,c++,algorithm,optimization,runtime,C++,Algorithm,Optimization,Runtime,我在计算向量元素的平均值和标准偏差。我有两个版本,我完全不明白为什么使用标准算法的版本比使用普通循环的版本慢 两个版本都使用此结构作为返回类型: struct MeanAndSigma { double mean; double sigma; }; 有循环的版本是这样的: MeanAndSigma getMeanAndSigma(const DVector& v){ MeanAndSigma ms; ms.mean = 0; for (int i

我在计算向量元素的平均值和标准偏差。我有两个版本,我完全不明白为什么使用标准算法的版本比使用普通循环的版本慢

两个版本都使用此结构作为返回类型:

struct MeanAndSigma {
    double mean;
    double sigma;
};
有循环的版本是这样的:

MeanAndSigma getMeanAndSigma(const DVector& v){
    MeanAndSigma ms;
    ms.mean = 0;
    for (int i=0;i<v.size();++i){ms.mean += v[i];}
    ms.mean = ms.mean / v.size();
    double sqsum = 0;
    for (int i=0;i<v.size();++i){sqsum += (v[i]-ms.mean)*(v[i]-ms.mean);}
    ms.sigma = std::sqrt(sqsum / (v.size()-1));   
    return ms;
}
meansandsigma getmeansandsigma(const-DVector&v){
平均和西格玛质谱;
ms.mean=0;

对于(int i=0;i我不认为程序是等价的。在第二个版本(使用算法)中,正在填充一个新的双精度向量,并且还涉及一个额外的迭代

你可以试试这个(c++11版本),它相当于第一个版本。我还没有试过运行它,它应该可以运行一些小的改动

MeanAndSigma getMeanAndSigma2(const DVector& v){
    MeanAndSigma ms;
    ms.mean = std::accumulate(v.begin(),v.end(),0.0) / v.size();
    double sqsum = std::accumulate(v.begin(),v.end(),
       [ms](double sum, double ve){ return sum + (ve-ms.mean)*(ve-ms.mean);}
    );
    ms.sigma = std::sqrt(sqsum / (v.size()-1));
    return ms;
}
没有lambdas(未测试,可能需要一些小的更改)


您是否在启用优化的情况下运行,因为第二个函数之类的代码从优化中获益匪浅。如果未启用优化,则时间度量基本上毫无意义。@tobi303这就引出了一个问题。当然,循环速度更快,所做的工作更少(首先,他们不会分配一个大的向量)。真正的问题应该是“我如何使用标准算法实现这个计算?”顺便说一句,这是一个很好的问题-可能会有帮助。@tobi303基本上,
GetMeansandSigma
接受向量的2个循环,而
GetMeansandSigma2
接受3个循环,我想这是根本原因。@tobi303将其替换为具有
double运算符()(double,double)的
struct
常量
运算符then@Mine:事实上,第二个解决方案需要4个循环,因为
diff
的构造函数初始化了它的所有
v.size()
条目。您将如何解决这个问题?@tobi303:您可以再次使用
std::accumulate()
而不是
std::transform()
,提供您自己的
二进制操作
函子,在将其添加到总数之前进行额外计算。抱歉,忘了提及我不能使用C++11。然而,praetorian已经为我指出了一些没有C++11时如何操作的方向。我只想尝试一下,但我想我会接受您的回答,因为问题是n没有提到任何关于C++11的内容,也没有标注非lambda版本,
MeanAndSigma getMeanAndSigma2(const DVector& v){
    MeanAndSigma ms;
    ms.mean = std::accumulate(v.begin(),v.end(),0.0) / v.size();
    double sqsum = std::accumulate(v.begin(),v.end(),
       [ms](double sum, double ve){ return sum + (ve-ms.mean)*(ve-ms.mean);}
    );
    ms.sigma = std::sqrt(sqsum / (v.size()-1));
    return ms;
}
class DiffSquare
{
    public:
        DiffSquare(double m) : _m(m) {}
        double operator()(double sum, double e)
        {
            return sum + (e - _m) * (e - _m);   
        }
    private:
        double _m;
};

MeanAndSigma getMeanAndSigma2(const DVector& v) {
    MeanAndSigma ms;
    ms.mean = std::accumulate(v.begin(),v.end(),0.0) / v.size();
    DiffSquare diff_square(ms.mean);
    double sqsum = std::accumulate(v.begin(),v.end(),
        0.0,
        diff_square
    );
    ms.sigma = std::sqrt(sqsum / (v.size()-1));
    return ms;
}