将结构化数据投影到std::向量的最有效方法是什么
What is the most efficient way to project structured data to a std::vector?
假设我有以下结构类型:
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;
}
还有其他建议吗?
您可以创建第二个结构的构造函数,如下所示:
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_struct
或YStruct y_struct(x_struct)
。然后简单地将第一个向量的每个元素复制到第二个。
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 });
}
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;
v
是std::vector
,需要双重间接,因为矢量包含指向数据所在位置的指针。在少数情况下,我被迫明确使用以下方法:
X* vp = &v[0];
for (int i=0,n=v.size(); i<n; i++) {
vp[i] = ...
}
相反,这释放了寄存器,并显著加快了执行速度,因为编译后的代码总是假设向量可以在循环期间重新分配,从而在每次迭代中重新执行两个间接步骤,即使重新分配在技术上是不可能的(根本没有调用外部代码,只是整数之间的简单操作,所有内容都是内联的)。
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法