Frage

Ist IO effiziente, aufgrund des Linux Disk-Buffer-Cache, bei der Lagerung in einem großen Regal häufig zugegriffen Python-Objekte als separate cPickle Dateien anstatt alle Objekte zu speichern?

Ist die Plattenpuffer-Cache arbeitet anders in diesen beiden Szenarien in Bezug auf Effizienz?

Es kann Tausende von großen Dateien sein (in der Regel um 100 MB, aber manchmal 1Gb), aber viel RAM (zB 64 Gb).

War es hilfreich?

Lösung

Ich weiß nicht, jeden theoretischen Weg zu entscheiden, welche Methode ist schneller, und auch wenn ich es tue, bin ich nicht sicher, würde ich ihm vertrauen. Lassen Sie uns also einen Code schreiben und testen Sie es.

Wenn wir unsere Pickles / shelve Manager in Klassen mit einer gemeinsamen Schnittstelle verpacken, dann wird es einfach sein, um sie zu tauschen in und aus Ihrem Code. Also, wenn zu einem späteren Zeitpunkt Sie entdecken, ist besser als die andere (oder entdecken einige noch besser) alles, was Sie zu tun haben, schreiben ist eine Klasse mit der gleichen Schnittstelle und Sie werden die neue Klasse in Ihren Code stopfen können, mit sehr wenig Änderung an irgendetwas anderes.

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)

Normalerweise Sie PickleManager wie folgt verwenden würde:

manager=PickleManager()
manager.load(...)
manager.store(...)

, während Sie die ShelveManager wie folgt verwenden würde:

with ShelveManager('/tmp/shelve.dat') as manager:        
    manager.load(...)
    manager.store(...)

Aber zu Testleistung, Sie so etwas tun könnte:

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())'

Mindestens auf meiner Maschine, kamen die Ergebnisse wie folgt aus:

                  read (ms)     write (ms)
PickleManager     9.26          7.92 
ShelveManager     5.32          30.9 

So ist es wie ShelveManager schaut Lesung kann schneller, aber PickleManager kann beim Schreiben schneller.

Achten Sie darauf, diese Tests selbst laufen. Timeit Ergebnisse können aufgrund von Python-Version variieren, Betriebssystem, Dateisystem-Typ, Hardware, usw.

Beachten Sie auch, meine write und read Funktionen erzeugen sehr kleine Dateien. Sie finden diese auf Daten testen möchten ähnlicher Ihren Anwendungsfall.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top