将结构化数据投影到std :: vector的最有效方法是什么?

时间:2014-10-24 05:46:25

标签: c++ vector stl projection

我们说我有以下结构类型:

struct XStruct {
   int a_value;
   int b_value;
}

struct YStruct {
   int c_value;
   int d_value;
};

现在我有以下向量:

std::vector<XStruct> m_x_values;

我想将数据投影到c_value s = b_value s和d_value s = a_value s

std::vector<YStruct> m_y_values;

最有效的方法是什么:

选项1:

m_y_values.clear();
m_y_values.reserve(m_x_values.size());

for(auto x : m_x_values)
{
    m_y_values.push_back({x.b_value, x.a_value});
}

选项2:

m_y_values.resize(m_x_values.size());
int i = 0;
for(auto x : m_x_values)
{
    m_y_values[i].c_value = x.b_value
    m_y_values[i].d_value = x.a_value;
    ++i;
}

还有其他建议吗?

3 个答案:

答案 0 :(得分:2)

您可以创建第二个结构的构造函数:

struct YStruct {
   explicit YStruct(const &XStruct x_struct)
   : c_value(x_struct.a_value)
   , d_value(x_struct.b_value)
   {};

   int c_value;
   int d_value;
};

您将可以使用y_struct = x_structYStruct y_struct(x_struct)。 然后简单地将第一个向量的每个元素复制到第二个。

答案 1 :(得分:1)

STL算法transform适用于此类问题。

std::vector<XStruct> x_values = { { 1, 2 }, {3, 4} };
std::vector<YStruct> y_values(x_values.size());

std::transform(x_values.begin(), x_values.end(), y_values.begin(), [](const XStruct& x){
    return YStruct{ x.b_value, x.a_value };
});

或者使用vector::emplace_back来节省一些YStruct施工时间,但调整矢量大小需要一些时间。

std::vector<XStruct> x_values = { { 1, 2 }, {3, 4} };
std::vector<YStruct> y_values;

for (const auto& x : x_values){
    y_values.emplace_back(YStruct{ x.b_value, x.a_value });
}

答案 2 :(得分:0)

可以使用一对迭代器初始化

std::vector,这允许使用这个习语:

std::vector<A> new_vect(old_vect.begin(), old_vect.end());

因此,通过定义Y接受const X&作为参数的构造函数,您将尽可能清晰简明地表达您的意图,让图书馆自由地做任何最好的事情。操作

委托图书馆并希望它做得最好不是一个总能获胜的策略(实际上根本没有)但是在std::vector的情况下,我有理由相信编译器实施者做了所有这些能尽可能快地完成手术。

如果有疑问(并且只有当你实际测量这个操作是你的代码的瓶颈并且不仅仅是猜测时),那么尝试测量其他方法,甚至可能检查生成的机器代码。它不应该经常发生。

根据我的经验,从性能的角度来看,我认为reserve + push_back版本是最糟糕的方法,因为今天的编译器不够智能(AFAIK)来检测这种模式。即使分配每个元素也可能不是最快的方式,因为当你写

v[i] = x;

vstd::vector,需要双重间接,因为向量包含指向数据所在位置的指针。在少数情况下,我被迫明确使用这种方法:

X* vp = &v[0];
for (int i=0,n=v.size(); i<n; i++) {
    vp[i] = ...
}
相反,这会释放寄存器并加速执行,因为编译后的代码总是假设在循环期间可以重新分配向量,因此在每次迭代时重做两个间接步骤,即使重新分配在技术上是不可能的(根本没有调用外部代码,只需在整数之间进行简单操作,内联所有内容。