大量の計算データを保存していますが、現在、必要なストレージの量を減らすためにポリモーフィック型を使用しています。終了時にオブジェクトを削除することを除いて、すべてが非常に高速であり、より良い代替手段が必要だと思います。コードは各ステップで状態を計算し、存在する条件に応じて特定の値を保存する必要があります。最悪のケースは完全なオブジェクトの状態を保存することであり、最良の状態はほとんど何も保存しないことです。(非常に単純化された)セットアップは次のとおりです。
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+pointer によるオーバーヘッドは、全体として、最大オブジェクトと最小オブジェクトのサイズの差 (sizeof によると少なくとも 200 バイト) よりもはるかに小さいです。多くの場合、最大のオブジェクトの代わりに最小のオブジェクトを使用でき、数千万ものオブジェクトが保存される可能性があるため、数ギガバイトのメモリ使用量を節約できます。基本クラスには正しいアイテムを見つけるために必要な情報が含まれているため、結果は非常に高速に検索できます。これは、実際の型に dynamic_cast で戻すことができます。ほとんどの場合、非常にうまく機能します。
唯一の問題は削除です。何千万ものオブジェクトがある場合、すべてのメモリを解放するのに数秒かかります。削除コードは各オブジェクトを反復処理しdelete results[i]
、仮想デストラクタを呼び出します。回避することは不可能ではありませんが、もっとエレガントな解決策が必要だと思います。
大きな連続したメモリ ブロックを (malloc などを使用して) 割り当てることで確実に実行できます。これは追跡され、ブロック内の空きメモリの次のバッチへの正しいポインタが生成されます。そのポインターは、ベクターに格納されます。メモリを解放するには、少数の大きなブロックで free() を呼び出す必要があります。vtable がなくなり (正しいキャストを保証するために、より小さな型フィールドに置き換えることができます)、スペースも節約されます。ただし、これは非常にCスタイルのソリューションであり、特にきれいではありません。
私が見落としているこの種の問題に対する C++ スタイルの解決策はありますか?