4

Python のネイティブ DBM は、Tokyo Cabinet や MongoDB などの NOSQL データベースよりもかなり高速である必要があると考えていました (Python DBM は機能とオプションが少なく、つまりシステムが単純であるため)。非常に単純な書き込み/読み取りの例でテストしました

#!/usr/bin/python
import time
t = time.time()
import anydbm
count = 0
while (count < 1000):
 db = anydbm.open("dbm2", "c")
 db["1"] = "something"
 db.close()
 db = anydbm.open("dbm", "r")
 print "dict['Name']: ", db['1'];
 print "%.3f" % (time.time()-t)
 db.close()
 count = count + 1

読み取り/書き込み: 1.3 秒 読み取り: 0.3 秒 書き込み: 1.0 秒

MongoDb のこれらの値は、少なくとも 5 倍高速です。それは本当に Python DBM のパフォーマンスですか?

4

2 に答える 2

15

Python には組み込みの DBM 実装がありません。DBM 機能は、AnyDBM、Berkeley DBM、GNU DBM などの幅広い DBM スタイルのサードパーティ ライブラリに基づいています。

Python のディクショナリの実装は、キーと値のストレージに関しては非常に高速ですが、永続的ではありません。高性能のランタイム キー値ルックアップが必要な場合は、ディクショナリの方が適している可能性があります。cpickle や shelve などで永続性を管理できます。起動時間が重要な場合 (およびデータを変更している場合は終了) - 実行時のアクセス速度よりも重要な場合 - DBM のようなものが優れています。

評価では、メイン ループの一部として、dbm オープン コールと配列ルックアップの両方を含めました。DBM を開いて 1 つの値を保存し、それを検索する前に閉じて再度開くというのは、かなり非現実的なユース ケースです。また、永続的なデータ ストアをそのような方法で管理する場合に見られる典型的なパフォーマンスの低下が見られます (かなり効率が悪い)。

要件によっては、高速なルックアップが必要で、起動時間をあまり気にしない場合は、DBM が解決策になる可能性がありますが、ベンチマークを実行するには、書き込みと読み取りのみをループに含めてください。以下のようなものが適しているかもしれません:

import anydbm
from random import random
import time

# open DBM outside of the timed loops
db = anydbm.open("dbm2", "c")

max_records = 100000

# only time read and write operations
t = time.time()

# create some records
for i in range(max_records):
  db[str(i)] = 'x'

# do a some random reads
for i in range(max_records):
  x = db[str(int(random() * max_records))]

time_taken = time.time() - t
print "Took %0.3f seconds, %0.5f microseconds / record" % (time_taken, (time_taken * 1000000) / max_records)

db.close()
于 2011-10-12T11:04:28.413 に答える