嵌入式密钥库在 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 瓶颈的服务——比如说,你正在编写一个 web 服务——,那么访问资源的开销可能并不重要。
也就是说,如果它们提供额外的服务,您可以看到使用外部数据库的一些优势。对于 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,您可以获得数据库的全部功能,而不仅仅是一个简单的数据存储。当然,如果有很多客户端饱和,或者有很多单次获取,与嵌入式资源相比,它的性能会很差。
至于 gdbm 竞争,Charles Leifer 在2014 年进行的一项基准测试表明,它可以在读取方面超越 KyotoCabinet,但在写入方面仍然是并列的,并且可以将 LevelDB 和 RocksDB 视为高级替代品。