如何有效地初始化大型类的对象
How to efficiently initialize objects of large class
>假设我有一个包含多个(+100)数据成员的类。对于这个问题,为了清楚起见,我们使用了一个只有 6 个成员的示例:
class A
{
public:
int v1, v2, v3, v4, v5, v6;
A(int a,
int b,
int c,
int d,
int e,
int f)
: v1(a),
v2(b),
v3(c),
v4(d),
v5(e),
v6(f){};
};
现在,假设我想创建此类的单个对象。 由于成员数量众多,我想在单独的函数中初始化对象,以免弄乱main
。据我所知,我可以通过两种方式做到这一点:
方法一:
A test()
{
return temp_a(1,2,3,4,5,6);
}
int main()
{
A a = test();
}
方法2:(通过引用传递)
void test(vector<A>& a)
{
A temp_a(1,2,3,4,5,6);
a.push_back(temp_a);
}
int main()
{
vector<A> a;
test(a);
}
问题在初始化大型类的对象时,这些方法中哪一种在效率和专业性方面最好?我个人更喜欢方法 2,因为我直接更改向量。缺点是每次我想访问对象的成员时都必须引用a[0]
。
方法 2 的效率较低,惯用语也较少C++。
由方法 1 引起的复制和/或移动几乎肯定会被编译器省略。 返回值优化(RVO)将导致A
对象从test()
内构造到其最终位置(a
),就好像你写了这样的东西一样:
A * test(void *a)
{
return new (a) A(1,2,3,4,5,6);
}
int main()
{
typename std::aligned_storage<sizeof(A), alignof(A)>::type a_mem;
A &a = *test(a_mem);
// The rest of your code.
// Technically this is not exception-safe, but for the purposes of
// illustration, assume that the following line will be called even if
// an exception is thrown between the line initializing the "a" reference
// and this line.
a.~A();
}
关键是,如果您认为这将是一个性能瓶颈,那么您应该进行基准测试来验证这一点。 编译器比我们聪明得多,它非常擅长优化很多东西。
任何瓶颈很可能都位于代码中的其他位置。
使你的代码对未来的维护者来说正确和明显,比提高一点性能更重要(除非你走在关键路径上)。 此外,编译器优化简单明了的代码比优化复杂的解决方法要容易得多。 (例如,在方法 2 中,编译器无法轻松优化由std::vector
引起的堆分配,因此您实际上是通过添加编译器无法透视的额外间接级别来取消优化。
相关文章:
- 将大型对象存储在无序映射中是否效率低下
- std::array 在存储大型对象时是否仍然对缓存友好?
- 在 c++ 中重置大型对象实例的最佳方法是什么
- 如何有效地初始化大型类的对象
- 封装与大型C 对象中的指针返回
- 通过引用传递大型对象时堆栈溢出
- 将大型python对象存储在RAM中以备将来使用
- C++内存中的大型对象集合是否正常
- 对象大型数组的内存使用量极大
- 将BSONObj对象存储在std::vector中会与大型文档发生冲突
- C++:使用指针存储/访问大型对象以避免内存不足
- Cython:如何移动大型对象而不复制它们
- 如何确定大型对象的性能成本(在C++中)
- 将大型对象放入堆中的最佳方式是什么
- 有效地使用python对象来迭代调用python函数的大型数据集
- 如何缓存1000个大型C++对象
- 将大型成员对象移出类
- 移动大型非指针基对象的语义
- 特征:如何防止大型对象的额外副本;在RHS上未实现完整矩阵的情况下分配结果
- 是否建议不要将大型STL对象作为值存储到std::unordered_map中?