我在想,Python的原生DBM应该比东京机柜、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.3s读: 0.3s写: 1.0s
MongoDb的这些值至少快5倍。这真的是Python DBM的性能吗?
发布于 2011-10-12 19:04:28
Python没有内置的DBM实现。它的数据库管理功能基于广泛的数据库管理风格的第三方库,如AnyDBM、Berkeley DBM和GNU DBM。
Python的字典实现对于键值存储来说非常快,但不是持久的。如果你需要高性能的运行时键值查找,你可能会找到一个更好的字典--你可以用像cpickle或shelve这样的东西来管理持久性。如果启动时间对您很重要(如果您正在修改数据,终止)-比运行时访问速度更重要-那么像DBM这样的东西会更好。
在您的评估中,作为主循环的一部分,您已经包含了dbm open调用和数组查找。在查找之前打开DBM来存储一个值,然后关闭并重新打开,这是一个非常不现实的用例,并且您会看到以这种方式管理持久性数据存储时的典型缓慢性能(效率非常低)。
根据您的需求,如果您需要快速查找,并且不太关心启动时间,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()发布于 2020-02-06 23:42:52
嵌入式密钥库在python3中已经足够快了。将本机字典作为基线,比如
for k in random.choices(auList,k=100000000):
a=auDict[k]
CPU times: user 1min 6s, sys: 1.07 s, total: **1min 7s**GDBM在这方面的表现并不差
%%time
with db.open("AuDictJson.gdbm",'r') as d:
for k in random.choices(auList,k=100000000):
a=d[str(k)]
CPU times: user 2min 44s, sys: 1.31 s, total: **2min 45s**甚至一个专门的预编译表,如json序列化列表的keyvy,也可以做几乎同样的事情。
%%time
d = keyvi.Dictionary("AuDictJson.keyvi")
for k in random.choices(auList,k=100000000):
a=d[str(k)].GetValue()
CPU times: user 7min 45s, sys: 1.48 s, total: 7min 47s一般而言,嵌入式数据库,特别是当它是只读和单用户时,应该总是期望赢得外部数据库,因为访问资源的套接字和信号量的开销。另一方面,如果你的程序是一个已经有一些外部I/O瓶颈-say的服务,你正在编写一个the服务,那么访问资源的开销可能并不重要。
也就是说,如果外部数据库提供额外的服务,您可以看到使用外部数据库的一些优势。对于Redis,考虑集合的联合。
%%time
for j in range(1000):
k=r.sunion(('s'+str(k) for k in random.choices(auList,k=10000)))
CPU times: user 2min 24s, sys: 758 ms, total: 2min 25s与gbm相同的任务处于相同的数量级。尽管redis仍然慢了五倍,但它还没有慢到丢弃它的程度。
%%time
with db.open("AuDictPSV.gdbm",'r') as d:
for j in range(1000):
a=set()
for k in random.choices(auList,k=10000):
a.update(d[str(k)].split(b'|'))
CPU times: user 33.6 s, sys: 3.5 ms, total: 33.6 s在这种情况下,通过使用redis,您可以获得数据库的全部功能,而不仅仅是一个简单的数据存储。当然,与嵌入式资源相比,在大量客户端饱和的情况下,如果使用大量的单个gets,它的性能将会很差。
至于gdbm的竞争,Charles Leifer的2014 benchmark表明,对于仍然并列写入的读取,它可以超过KyotoCabinet,并且可以将LevelDB和RocksDB作为高级替代方案。
https://stackoverflow.com/questions/7738272
复制相似问题