C++ 提高std::vector的存储容量/性能
我正在构建一个建模软件,我有一些关于如何获得最佳性能的问题 1) 我应该使用C++ 提高std::vector的存储容量/性能,c++,multithreading,c++11,inheritance,vector,C++,Multithreading,C++11,Inheritance,Vector,我正在构建一个建模软件,我有一些关于如何获得最佳性能的问题 1) 我应该使用std::vector还是std::vector? 我的类相当复杂/庞大,我认为使用第二个选项更好,因为std::vector尝试连续分配内存,可能没有连续的内存块来存储一百万个类,但当我只存储指针时,类不必连续存储,只需存储指针,计算机可能有空间这样做。这个推理正确吗 2) 正如我所说,我将拥有数百万个类,(为了进行适当的模拟,我需要>十亿个类),在这里使用继承是明智的吗? 在我的模拟中,有多个不同的类型继承自同一基类
std::vector
还是std::vector
?
我的类相当复杂/庞大,我认为使用第二个选项更好,因为std::vector尝试连续分配内存,可能没有连续的内存块来存储一百万个类,但当我只存储指针时,类
不必连续存储,只需存储指针,计算机可能有空间这样做。这个推理正确吗
2) 正如我所说,我将拥有数百万个类
,(为了进行适当的模拟,我需要>十亿个类
),在这里使用继承是明智的吗?
在我的模拟中,有多个不同的类型继承自同一基类
class A - class B
- class C
- class D
我是否应该避免继承,因为我一直听说使用继承会导致性能损失
3) 另外,如何将所有这些不同的类存储在std::vector中?
std::vector
或std::vector
是否可以存储所有继承自基类的类B、类C、类D
4) 在之前版本的程序中,我使用了多线程,通过使不同的进程处理std::vector的不同部分,有更好的方法来执行线程吗
5) 我应该使用智能指针吗?既然我有这么多对象,它们会降低性能吗
我正处于计划阶段,非常感谢您的帮助在专业的环境中,我每天都会处理这样的问题(我是一个C++程序员,处理大数据集)。因此,我在这里要说的,既是一个答案,也是一个个人建议。我不会对简单的部分全力以赴:
1-是的存储指针,它将比重新分配和移动时间快得多,比完整类对象快得多
2-是的,如果对象有相关的信息,请使用继承,我想在这种情况下,它们很可能会按照您的想法执行。如果没有,你为什么要把它们放在一起
3-使用指向基类(父对象)的智能指针存储它们,因此您可以添加一个虚拟“get_type”函数来返回和枚举,并在需要时转换为子对象。如果您不经常需要子数据,这将节省提供多个虚拟方法的开销
4-有争议,但更简单的方法是将较大数组的各个部分线程化(当您处理庞大的复杂数据时,越简单越好)
每个人都知道调试的难度是编写程序的两倍。因此,如果你在编写程序时尽可能聪明,你将如何调试它?~Brian Kernighan
5-使用智能指针会有一些小的惩罚(,但是在我看来,与易用性和复杂性损失相比,惩罚(特别是使用unique_ptr)是如此之小,这绝对值得
把它们放在一起:
class Abstract_Parent;
std::vector<std::unique_ptr<Abstract_Parent>> Data;
enum ChildType {Child_1 = 0, Child_2 = 1};
class Abstract_Parent
{
public:
virtual ChildType GetType() = 0;
}
class Child_One
{
public:
virtual ChildType GetType() { return Child_1; }
}
class Child_Two
{
public:
virtual ChildType GetType() { return Child_2; }
}
void Some_Function()
{
//this is how to insert a child-object
std::unique_ptr<Abstract_Parent> Push_me_Back(new Child_One());
Data.Push_Back(std::move(Push_me_Back));
if(Data[0]->GetType() == Child_1)
{
Child_1 *Temp_Ptr = dynamic_cast<Child_One*> Data[0];
Temp_Ptr->Do_Something_Specific();
}
}
类抽象\u父类;
std::矢量数据;
枚举子类型{Child_1=0,Child_2=1};
类抽象\u父类
{
公众:
虚拟子类型GetType()=0;
}
一班
{
公众:
虚拟子类型GetType(){return Child_1;}
}
二班
{
公众:
虚拟子类型GetType(){return Child_2;}
}
使某些函数无效()
{
//这是如何插入子对象
std::unique_ptr Push_me_Back(新的子对象());
Data.Push_Back(标准::move(Push_me_Back));
if(数据[0]->GetType()==子项1)
{
Child_1*Temp_Ptr=动态_cast数据[0];
Temp_Ptr->Do_some_Specific();
}
}
1.)这取决于您的用例。如果您希望通过基类指针访问对象,则将使用指针。另一方面,您将失去连续内存和代码和数据的缓存位置的优势
2.)如果您需要10亿个实例,则每个对象的每一个额外数据都会增加内存占用。例如,指向8字节虚拟函数表(vptr)的额外指针会增加8 GB的内存需求。在没有虚拟基类的情况下,将每种类型存储在不同的向量中不会产生此开销
2b)是的,如果您以性能为目标,则应避免使用虚拟函数继承。如果使用不同的实现调用虚拟函数,则指令缓存将被破坏。至少可以按类型对大向量进行排序,以最小化此问题
3.)如果选择具有虚拟函数的基类,则必须使用指针选项来防止切片
4.)需要更多信息,应在单独的问题中回答
5.)每个间接操作都会降低性能
1) 我应该使用std::vector
还是std::vector
假二分法。还有几个其他选择:
boost::ptr_向量
std::vector
- 可能更多
就我个人而言,我喜欢boost::ptr_vector
,因为它存储一个拥有的指针(因此内存分配是自动完成的)。但是当访问成员时,它们作为对象(而不是指针)的引用返回。因此,与其他技术相比,将它们与标准算法一起使用大大简化了
我的类非常复杂/很大,我认为使用第二个选项更好,因为std::vector尝试连续分配内存,并且可能没有连续的内存块来存储一百万个类
这里真正的问题是,您是否可以预先计算向量的最大大小和所需的空间量。如果您能够做到这一点(从而避免任何复制成本)std::vector
将是最好的解决方案
这是