Pythonで柔軟で軽量なインメモリデータベースを構築していますが、値の検索方法とインデックスの使用方法にパフォーマンスの問題があることがわかりました。これを改善するために、速度とメモリ使用量のバランスをとろうとして、いくつかのオプションを試しました。私の現在の実装では、dictのdictを使用して、レコード(オブジェクト参照)およびフィールド(オブジェクト参照)ごとにデータを格納しています。したがって、たとえば、3つのフィールドを持つ3つのレコードがあり、データの一部が欠落している場合(つまり、NULL値)::
{<Record1>: {<Field1>: 4, <Field2>: 'value', <Field3>: <Other Record>},
{<Record2>: {<Field1>: 4, <Field2>: 'value'},
{<Record3>: {<Field1>: 5}}
numpy配列を検討しましたが、オブジェクトインスタンスを配列インデックスにマップするために2つの辞書が必要になるため、パフォーマンスが向上するかどうかはわかりません。
インデックスは、2つに分割されたリストのペアを使用して実装され、基本的に値からレコードインスタンスへのマップとして機能します。たとえば、上記のインデックスField1>
:
[[4, 4, 5], [<Record1>, <Record2>, <Record3>]]
以前は単純なビンの辞書を使用していましたが、これでは範囲のルックアップができませんでした(たとえば、すべての値が5より大きい)(あいまい一致についてはPythonハッシュテーブルを参照してください)。
私の質問はこれです。複数のオブジェクト参照があり、インデックスに同じ値の複数のコピーがあるのではないかと心配しています。これらの重複する参照はすべて実際により多くのメモリを使用しますか、それともPythonでの参照は安価ですか?私の代替案は、各オブジェクトにテンキーを関連付けようとすることです。これにより、少なくとも256まで改善される可能性がありますが、Pythonが参照を処理して、これが本当に優れているかどうかを知るには十分な知識がありません。
誰かがこれを管理するためのより良い方法の提案がありますか?
Cで重要な部分を再実装することは、最後の手段として残しておきたいオプションです。
興味のある人のために、私のコードはここにあります。
編集1:
簡単に言えば、メモリ使用量の観点から、次のうちどれがより効率的であるかという質問です。ここa
で、はオブジェクトインスタンスでありi
、は整数です。
[a] * 1000
または
[i] * 1000, {a: i}
編集2:
既存のシステムを使用していることを示唆するコメントが多数あるため、ここに私の要件があります。誰かがこれらすべてを満たすシステムを提案できれば、それは素晴らしいことですが、これまでのところ、私はそれを実現するものを見つけていません。それ以外の場合、私の元の質問は、Pythonでの参照のメモリ使用量に関連しています。
- 軽量でメモリ内にある必要があります。間違いなくクライアント/サーバーモデルではありません。
- テーブルの変更、フィールドの変更、ルールの変更などをその場で簡単に行える必要があります。
- 非常に複雑な検証ルールを簡単に適用する必要があります。SQLはこの要件を満たしていません。非常に複雑なステートメントを作成できる場合もありますが、それは決して簡単なことではありません。
- テーブル間の結合と関連付けをサポートする必要があります。多くのNoSQLデータベースは、結合をまったくサポートしていないか、せいぜい単純な結合のみをサポートしています。
- データを任意のファイル形式でロードおよび保存する方法をサポートする必要があります。私は現在、必要に応じて新しいフォーマットを簡単に追加できるフレームワークを提供することでこれを実装しています。
- (前のポイントのようにデータを保存する以外に)永続性を必要とせず、大量のデータ、つまり数百万レコード以下を処理する必要もありません。通常、私は数千を扱っています。