Je ne connais pas de méthode théorique pour décider quelle méthode est la plus rapide, et même si je l'ai fait, je ne suis pas sûr de lui faire confiance. Alors écrivez du code et testez-le.
Si nous emballons nos gestionnaires pickle/shelve dans des classes avec une interface commune, il sera alors facile de les échanger dans et hors de votre code. Donc, si à un moment donné, vous découvrez que l'un est meilleur que l'autre (ou que vous en découvrirez d'autres), il vous suffit d'écrire une classe avec la même interface et vous pourrez ajouter la nouvelle classe à votre code. très peu de modification à quoi que ce soit d'autre.
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)
Normalement, vous devriez utiliser PickleManager comme ceci:
manager=PickleManager()
manager.load(...)
manager.store(...)
pendant que vous souhaitez utiliser le ShelveManager comme ceci:
with ShelveManager('/tmp/shelve.dat') as manager:
manager.load(...)
manager.store(...)
Mais Pour tester la performance, vous pouvez faire quelque chose comme ceci:
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())'
Au moins sur ma machine, les résultats sont comme ceci:
read (ms) write (ms)
PickleManager 9.26 7.92
ShelveManager 5.32 30.9
il ressemble ShelveManager peut être plus rapide à la lecture, mais PickleManager peut être plus rapide à l'écriture.
Veillez à exécuter ces tests vous-même. Les résultats Timeit peuvent varier selon la version de Python, OS, type de système de fichiers, matériel, etc.
Notez également que mes fonctions write
et read
génèrent de très petits fichiers. Vous aurez envie de tester cela sur des données plus similaires à votre cas d'utilisation.
Comme toujours, le pari le plus sûr est de l'essayer au lieu de méditer ceci et cela. – delnan
Bien sûr, mais j'aimerais savoir comment python interagit avec le cache du tampon de disque Linux, dont je ne sais rien. – ricopan
Je suis sûr que Python n'interagit pas directement avec un cache de système d'exploitation ... les performances dépendront du système de fichiers lui-même. Faites simplement de la taille du pickle un paramètre et lancez des benchmarks. Mon instinct me dit que si vous lisez/écrivez beaucoup, vous êtes mieux avec une étagère. Si vous faites des lectures/écritures peu fréquentes, respectez les cornichons individuels. –