Является ли Python DBM действительно быстрым? - PullRequest
4 голосов
/ 12 октября 2011

Я думал, что нативная СУБД Python должна быть намного быстрее, чем базы данных NOSQL, такие как Tokyo Cabinet, MongoDB и т. Д. (Так как СУБД Python имеет меньшие возможности и опции; т.е. более простая система)Я протестировал на очень простом примере записи / чтения:

#!/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?

1 Ответ

14 голосов
/ 12 октября 2011

Python не имеет встроенной реализации DBM. Он базирует свои функции DBM на широком спектре сторонних библиотек в стиле DBM, таких как AnyDBM, Berkeley DBM и GNU DBM.

Реализация словаря Python действительно быстрая для хранения значения ключа, но не постоянная. Если вам нужен высокопроизводительный поиск значений ключей во время выполнения, вы можете найти словарь лучше - вы можете управлять постоянством с помощью чего-то вроде cpickle или shelve. Если для вас важно время запуска (и если вы изменяете данные, завершение) - что важнее, чем скорость доступа во время выполнения - тогда лучше использовать что-то вроде DBM.

В вашей оценке как часть основного цикла вы включили как вызовы dbm open, так и поиск по массиву. Это довольно нереалистичный вариант использования: открыть СУБД для хранения одного значения и закрытия, а затем снова открыть его, прежде чем искать его, и вы видите типичную медленную производительность, которая наблюдается при управлении постоянным хранилищем данных таким совсем неэффективно).

В зависимости от ваших требований, если вам нужны быстрые поиски и вас не слишком заботит время запуска, 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()
...