2010-10-30 27 views
3

L'E/S est-elle plus efficace, en raison du cache du tampon de disque Linux, lors du stockage d'objets python fréquemment accédés en tant que fichiers cPickle distincts au lieu de stocker tous les objets dans une grande étagère?Est-ce que le cache du tampon de disque linux rend python cPickle plus efficace que shelve?

Le cache du tampon de disque fonctionne-t-il différemment dans ces deux scénarios en ce qui concerne l'efficacité?

Il peut y avoir des milliers de fichiers volumineux (généralement autour de 100 Mo, mais parfois 1 Go), mais beaucoup de RAM (par exemple 64 Go).

+1

Comme toujours, le pari le plus sûr est de l'essayer au lieu de méditer ceci et cela. – delnan

+0

Bien sûr, mais j'aimerais savoir comment python interagit avec le cache du tampon de disque Linux, dont je ne sais rien. – ricopan

+0

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. –

Répondre

2

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.

+0

Bel exemple, merci. Je l'exécuterai plus longuement pendant la nuit sur mes cas de test et rendrai compte. – ricopan