多态数据存储的替代方案

Alternatives for polymorphic data storage

本文关键字:方案 数据 存储 多态      更新时间:2023-10-16

我正在存储大量计算数据,目前我正在使用多态类型来减少所需的存储量。除了在我完成后删除对象之外,一切都非常快,我认为一定有更好的选择。代码计算每一步的状态,并根据当前的条件存储某些值。最坏的情况是存储完整的对象状态,而最好的状态是几乎不存储任何内容。(非常简化的)设置如下:

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字节)。由于通常可以使用最小的对象而不是最大的对象,并且可能存储数千万个对象,因此可以节省几GB的内存使用量。然后可以非常快速地搜索结果,因为基类包含找到正确项所需的信息,然后可以将该项动态化为其真实类型。它在大多数情况下都很好用。

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

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

对于我忽略的这类问题,有没有C++风格的解决方案?

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

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