Кэш буфера BINUX Disk делает Python Cpickle более эффективным, чем Slow?

StackOverflow https://stackoverflow.com/questions/4060937

Вопрос

Это более эффективно, из-за кэша буфера диска Linux, при хранении часто доступа к объектам Python в качестве отдельных файлов CPICKLE вместо хранения всех объектов на одной большой полке?

Кэш-память диска работает по-разному в этих двух сценариях относительно эффективности?

Там могут быть тысячи больших файлов (как правило, около 100 МБ, но иногда 1 ГБ), но много баран (например, 64 ГБ).

Это было полезно?

Решение

Я не знаю ни о каком теоретическом способе решить, какой метод быстрее, и даже если я сделал, я не уверен, что доверял этому. Так что давайте напишем какой-нибудь код и проверим его.

Если мы упаковываем наши менеджеры Sicle / Shella в классах с общим интерфейсом, то будет легко поменять их в и выходить из вашего кода. Итак, если в какой-то будущей точке вы обнаружите, что лучше, чем другие (или обнаружить немного еще лучше), все, что вам нужно сделать, это написать класс с одним и тем же интерфейсом, и вы сможете подключить новый класс в свой код с Очень мало модификации для всего остального.

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, OS, типа файловой системы, оборудования и т. Д.

Кроме того, обратите внимание мой write а также read Функции генерируют очень маленькие файлы. Вы захотите проверить это на данных, более похожи на ваш регистр использования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top