c++ - Why this code is getting slower when I use std::algorithms instead of plain loops? -
i calculating mean , standard deviation of elements of vector. have 2 versions of , puzzled why version using standard algorithms slower 1 using plain loops.
both version use struct return type:
struct meanandsigma { double mean; double sigma; };
and version loops this:
meanandsigma getmeanandsigma(const dvector& v){ meanandsigma ms; ms.mean = 0; (int i=0;i<v.size();++i){ms.mean += v[i];} ms.mean = ms.mean / v.size(); double sqsum = 0; (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; }
and 1 algorithms:
meanandsigma getmeanandsigma2(const dvector& v){ meanandsigma ms; ms.mean = std::accumulate(v.begin(),v.end(),0.0) / v.size(); dvector diff(v.size()); std::transform(v.begin(),v.end(),diff.begin(), std::bind2nd(std::minus<double>(), ms.mean)); double sqsum = std::inner_product(diff.begin(),diff.end(),diff.begin(),0.0); ms.sigma = std::sqrt(sqsum / (v.size()-1)); return ms; }
when measure time take per 10k calls vector 10k elements ~2.0 seconds version loops , ~3.2 seconds 1 algorithms. why this?
i compared cpu time , real time, seems if both running (as expected) on single cpu. doing stupidly wrong in using algorithms?
edit: not claiming, 2 versions equivalent. nevertheless have expected second version faster. pointed out in comments , answer, second version uses iteration on elements , dvector
(which btw typedef std::vector<double>
). however, not familiar enough standard algorithms improve second version. so, question is:
how can improve version algorithms faster 1 using plain loops?
i don't think programs equivalent. in second version (using algorithms) new vector of doubles being populated , iteration involved.
you try (c++11 version), equivalent of first version. haven't tried running it, should work minor changes.
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; }
without lambdas (not tested, might need minor changes)
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; }
Comments
Post a Comment