0

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データベースは、結合をまったくサポートしていないか、せいぜい単純な結合のみをサポートしています。
  • データを任意のファイル形式でロードおよび保存する方法をサポートする必要があります。私は現在、必要に応じて新しいフォーマットを簡単に追加できるフレームワークを提供することでこれを実装しています。
  • (前のポイントのようにデータを保存する以外に)永続性を必要とせず、大量のデータ、つまり数百万レコード以下を処理する必要もありません。通常、私は数千を扱っています。
4

3 に答える 3

1

各参照は事実上ポインタであり、各ポインタは少量のメモリを必要とします。

メモリプロファイラー を使用して、行ごとにメモリ使用量を表示できます。このようにして、参照を作成したときに何が起こるかを確認できます。

于 2012-12-03T14:25:36.860 に答える
0

Pythonは動的メモリ管理の特定の実装を指定していませんが、言語のセマンティクスから、参照がCポインターと同様のメモリを使用していると推測できます。

于 2012-12-03T14:22:38.367 に答える
0

FWIW、私は100x100構造でいくつかのテストを実行し、まばらに入力された辞書構造、完全に入力された辞書構造、リスト、およびnumpy配列をテストしました。後者の2つには、インデックスへのオブジェクト参照をマッピングする辞書がありました。構造内のすべてのアイテムをインデックスで取得するタイミングを設定し(スパース辞書で欠落データの番兵を返す)、合計サイズも報告しました。私の結果はやや意外でした:

Structure     Time     Size
============= ======== =====
full dict     0.0236s  6284
list          0.0426s  13028
sparse dict   0.1079s  1676
array         0.2262s  12608

したがって、最速で2番目に小さいのは完全な口述であり、key in dictチェックを実行する必要がなかったためと考えられます。

于 2012-12-05T13:54:35.393 に答える