我不知道任何理论上的方法来决定哪种方法更快,即使我知道了,我也不确定我是否会相信它。所以让我们编写一些代码并测试它。
如果我们将 pickle/shelve 管理器打包到具有公共接口的类中,那么将它们换入和换出代码将很容易。因此,如果在未来某个时刻你发现一个比另一个更好(或发现一些更好的方法),你所要做的就是编写一个具有相同接口的类,你就可以将新类插入到你的代码中对其他东西的修改很少。
test.py:
import cPickle
import shelve
import os
class PickleManager(object):
def store(self,name,value):
with open(name,'w') as f:
cPickle.dump(value,f)
def load(self,name):
with open(name,'r') as f:
return cPickle.load(f)
class ShelveManager(object):
def __enter__(self):
if os.path.exists(self.fname):
self.shelf=shelve.open(self.fname)
else:
self.shelf=shelve.open(self.fname,'n')
return self
def __exit__(self,ext_type,exc_value,traceback):
self.shelf.close()
def __init__(self,fname):
self.fname=fname
def store(self,name,value):
self.shelf[name]=value
def load(self,name):
return self.shelf[name]
def write(manager):
for i in range(100):
fname='/tmp/{i}.dat'.format(i=i)
data='The sky is so blue'*100
manager.store(fname,data)
def read(manager):
for i in range(100):
fname='/tmp/{i}.dat'.format(i=i)
manager.load(fname)
通常,您会像这样使用 PickleManager:
manager=PickleManager()
manager.load(...)
manager.store(...)
当您像这样使用 ShelveManager 时:
with ShelveManager('/tmp/shelve.dat') as manager:
manager.load(...)
manager.store(...)
但要测试性能,您可以执行以下操作:
python -mtimeit -s'import test' 'with test.ShelveManager("/tmp/shelve.dat") as s: test.read(s)'
python -mtimeit -s'import test' 'test.read(test.PickleManager())'
python -mtimeit -s'import test' 'with test.ShelveManager("/tmp/shelve.dat") as s: test.write(s)'
python -mtimeit -s'import test' 'test.write(test.PickleManager())'
至少在我的机器上,结果是这样的:
read (ms) write (ms)
PickleManager 9.26 7.92
ShelveManager 5.32 30.9
所以看起来 ShelveManager 的读取速度可能更快,但 PickleManager 的写入速度可能更快。
请务必自己运行这些测试。 Timeit 结果可能因 Python 版本、操作系统、文件系统类型、硬件等而异。
另外,请注意我的 write 和 read 函数会生成非常小的文件。您需要在与您的用例更相似的数据上对此进行测试。