时IO更有效,由于Linux磁盘缓存,当存储频繁访问Python对象作为单独的cPickle文件,而不是存储在一个大的货架中的所有对象?

是否磁盘缓冲缓存在这两个场景相对于效率不同地操作?

有可能数以千计的大文件(一般在100兆,但有时1GB),但大部分RAM(例如64 Gb)的

有帮助吗?

解决方案

我不知道任何理论方法来决定哪种方法更快,甚至如果我这样做,我不知道我会相信它。因此,让我们写一些代码并进行测试。

如果我们有一个共同的接口封装在课堂上我们的泡菜/货架管理,那么这将是容易掉并排出你的代码。所以,如果在未来的某个时刻,你发现一个比其他更好的(或者发现一些更好的方法),所有你需要做的就是写一个类具有相同的接口,你就可以插入新的类到你的代码很小的修改,以其他任何东西。

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可以在写更快。

确保自己运行这些测试。 Timeit结果可由于Python中,OS,文件系统类型,硬件等的版本而异

另外,请注意我的writeread功能产生非常小的文件。你要测试这个数据更类似于你的使用情况。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top