Я не знаю ни одного теоретического способа решить, какой метод быстрее, и даже если бы я это сделал, я не уверен, что доверю этому. Итак, давайте напишем некоторый код и протестируем его.
Если мы упаковываем наши менеджеры 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 может быть быстрее при записи.
Обязательно запустите эти тесты самостоятельно. Результаты могут меняться в зависимости от версии Python, ОС, типа файловой системы, аппаратного обеспечения и т. Д.
Также обратите внимание, что мои функции write
и read
генерируют очень маленькие файлы. Вы можете проверить это на данных, более похожих на ваш вариант использования.