多态数据存储的替代方案

时间:2013-07-18 23:26:07

标签: c++ memory polymorphism delete-operator

我正在存储大量的计算数据,而我目前正在使用多态类型来减少所需的存储量。一切都非常快,除了在我完成时删除对象,我认为必须有更好的选择。代码计算每个步骤的状态,并根据存在的条件,它需要存储某些值。最糟糕的情况是存储完整的对象状态,最佳状态几乎不存储。 (非常简化)设置如下:

class BaseClass
{
public:
    virtual ~BaseClass() { }

double time;
    unsigned int section;
};

class VirtualSmall : public BaseClass
{
public:
    double values[2];
    int othervalue;
};

class VirtualBig : public BaseClass
{
public:
    double values[16];
    int othervalues[5];
};

...

std::vector<BaseClass*> results(10000);

在计算期间生成适当的对象类型,并且指向它的指针存储在向量中。 vtable +指针的开销总体上小于最大和最小对象之间的大小差异(根据sizeof至少为200字节)。由于通常可以使用最小的对象而不是最大的对象,并且可能存储有数千万个对象,因此可以节省几千兆字节的内存使用量。然后可以非常快速地搜索结果,因为基类包含找到正确项目所需的信息,然后可以将dynamic_cast返回到它的真实类型。它在很大程度上都很有效。

唯一的问题是删除。当有数千万个对象时,需要几秒钟才能释放所有内存。删除代码遍历每个对象和调用虚拟析构函数的delete results[i]。虽然解决这个问题并非不可能,但我认为必须有更优雅的解决方案。

绝对可以通过分配较大的连续内存块(使用malloc或类似内容)来完成,这些内存会被跟踪,然后某些内容会生成指向块内下一批空闲内存的正确指针。然后该指针存储在向量中。为了释放内存,较少数量的大块需要调用free()。没有更多的vtable(它可以被更小的类型字段替换以确保正确的转换),这也节省了空间。这是一个非常C风格的解决方案,但并不是特别漂亮。

我忽略了这类问题的C ++风格解决方案吗?

1 个答案:

答案 0 :(得分:1)

您可以为您的类重载“new”运算符(即void * VirtualSmall :: operator new(size_t)),并实现它们以从自定义分配器获取内存。我会为每个派生类使用一个块分配器,这样每个块大小都是它应该存储的类的倍数。

当需要清理时,告诉每个分配器释放所有块。不会调用析构函数,因此请确保您不需要它们。