Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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++ boost::transform与std::transform_C++_Algorithm_Boost_Transform_Std - Fatal编程技术网

C++ boost::transform与std::transform

C++ boost::transform与std::transform,c++,algorithm,boost,transform,std,C++,Algorithm,Boost,Transform,Std,从下面的代码片段中,我是否应该得出这样的结论:std::transform优于boost::transform,因为前者比后者使用更少的初始化和析构函数,所以效率可能更高 #include <algorithm> #include <boost/range/algorithm.hpp> class Ftor { public: Ftor(const Ftor& rhs) : t(rhs.t) { std::cout << "

从下面的代码片段中,我是否应该得出这样的结论:
std::transform
优于
boost::transform
,因为前者比后者使用更少的初始化和析构函数,所以效率可能更高

#include <algorithm>
#include <boost/range/algorithm.hpp>
class Ftor {
public:
    Ftor(const Ftor& rhs) : t(rhs.t)
    { std::cout << " Ftor : copy\n"; }
    Ftor(float rate) : t(rate)
    { std::cout << " Ftor : init\n"; }
    ~Ftor()
    { std::cout << "~Ftor : ...\n"; }
    float operator() (float x) { return x < t ? 0.0 : 1.0; }
private:
    float t;
};

typedef std::vector<float> vec_t;

int main (void) 
{
    vec_t arg(/*...*/);
    vec_t val(arg.size());
    float x = 1.0;
    /* Standard transform test */
    std::cout << "Standard transform:\n";
    std::transform(arg.begin(), arg.end(), val.begin(), Ftor(x));
    std::cout << "Boost transform:\n";
    /* Boost transform test */
    boost::transform(boost::make_iterator_range(arg.begin(), arg.end()),
                     val.begin(), Ftor(x));
}
标准转换使用2个调用。Boost transform使用4个调用。标准转换获胜。还是

附录

正如@sehe所建议的那样,
std::ref
transform
的每个调用保存一个构造函数,
boost::transform
只使用一个调用。但是
std::ref
不能将临时变量作为参数。但是,将
传递到f(x)
是可以的,因为后者有一个明确的地址

在循环内调用transform时考虑构造函数/析构函数调用。我现在有两个boost选项:

std::cout << "with std::ref\n";
for (/*...*/) {
    x = ...;
    f = Ftor(x);
    boost::transform(arg, val.begin(), std::ref(f));
}

std::cout << "with temporary\n";
for (/*...*/) {
    x = ...;
    boost::transform(arg, val.begin(), Ftor(x));
}
我有一个gcc(ubuntu4.8.4-2ubuntu1~14.04)4.8.4 有或没有
-O3
产生相同的结果

构造函数/析构函数是否“昂贵”与
操作符()有关。它是一个最终产品,它将执行不太苛刻的数学运算,与上面的例子没有什么不同


STL算法允许复制其谓词/函子。这主要是因为它们是按值传递的

您看到的是,
boost
执行一个转发呼叫

有什么问题吗? 通常不会。编译器非常擅长内联、拷贝省略和依赖性分析

很可能,生成的代码最终完全相同

当然,添加
cout
语句完全破坏了这一点。比较生成的代码,不要让构造函数/析构函数的副作用破坏它

公平比较为STL和Boost变体生成相同的代码:

修理 按照STL(和boost算法)的设计方式,如果需要,可以通过引用显式传递函子。您可以使用
std::ref
进行以下操作:

#include <algorithm>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/range/algorithm.hpp>

class Ftor {
  public:
    Ftor(const Ftor &rhs) : t(rhs.t) { std::cout << " Ftor : copy" << std::endl; } 
    Ftor(float rate) : t(rate)       { std::cout << " Ftor : init" << std::endl; } 
    ~Ftor()                          { std::cout << "~Ftor : ..."  << std::endl; } 
    float operator()(float x)        { return x; }  

  private:
    float t;
};

typedef std::vector<float> vec_t;

int main(void) {
    vec_t arg(190, 1), val(arg.size());

    {
        std::cout << "STL transform: " << std::endl;
        Ftor f(1.0);
        std::transform(arg.begin(), arg.end(), val.begin(), std::ref(f));
    }
    std::cout << "-----\n";

    {
        std::cout << "Boost transform: " << std::endl;
        Ftor f(1.0);
        boost::transform(arg, val.begin(), std::ref(f));
    }
    std::cout << "-----\n";
}

注意不管发生什么,在容器上使用范围算法并构造一个范围
boost::make_iterator_range(arg.begin(),arg.end())
而不是仅仅使用
arg
,这是非常讽刺的:

boost::transform(arg, val.begin(), Ftor(x));

公平比较为STL和Boost变体生成相同的代码:公平比较的投票结果为向上。。。讽刺的是:DIf我替换了
boost::transform(arg,val.begin(),std::ref(f))末尾附近的行通过
boost::transform(arg,val.begin(),std::ref(Ftor(1.0))我得到一个错误:使用已删除的函数'void std::ref(const _Tp&)[with _Tp=Ftor]'。给出了什么?你不能安全地将引用传递给临时用户。这是一个内置于boosts引用包装类中的安全预防措施,因此,如果我在一个循环中有大量的
transform
s,那么开销可能会计算在内。。。我更喜欢A:
用于(/*…*/){tmp=Ftor(x);boost::transform(arg,val.begin(),std::ref(tmp));}
还是B:
用于(/*…*/){boost::transform(arg,val.begin(),Ftor(x));}
编辑几乎没有意义。为什么成员变量
t
甚至没有在functor中使用?
return(xOh god.我真的需要检查我的眼睛。不管怎样,等待基准代码(或者代码试图实现什么。可能有更好的算法方法)重新编辑。这只是计算你不应该计算的东西。实际的基准在哪里?
boost::transform(arg, val.begin(), Ftor(x));