首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux磁盘缓冲缓存是否使python cPickle比shelve更高效?

linux磁盘缓冲缓存是否使python cPickle比shelve更高效?
EN

Stack Overflow用户
提问于 2010-10-31 06:24:14
回答 1查看 664关注 0票数 4

当将频繁访问的python对象存储为单独的cPickle文件而不是将所有对象存储在一个大架子上时,IO效率是否更高,这是由于linux磁盘缓冲区缓存?

在效率方面,磁盘缓冲区缓存在这两个场景中的操作是否不同?

可能有数千个大文件(通常在100Mb左右,但有时是1 Gb),但RAM很大(例如64 Gb)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-10-31 08:13:29

我不知道任何理论上的方法来决定哪种方法更快,即使我这样做了,我也不确定我是否会相信它。所以让我们编写一些代码并对其进行测试。

如果我们将pickle/shelve管理器打包在具有公共接口的类中,那么在代码中和代码中交换它们将很容易。因此,如果在将来的某个时刻,您发现其中一个比另一个更好(或者发现一些更好的方法),您所要做的就是编写一个具有相同接口的类,并且您将能够将新类插入到您的代码中,而只需对其他任何东西进行很少的修改。

test.py:

代码语言:javascript
复制
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:

代码语言:javascript
复制
manager=PickleManager()
manager.load(...)
manager.store(...)

当您像这样使用ShelveManager时:

代码语言:javascript
复制
with ShelveManager('/tmp/shelve.dat') as manager:        
    manager.load(...)
    manager.store(...)

但是要测试性能,您可以这样做:

代码语言:javascript
复制
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())'

至少在我的机器上,结果是这样的:

代码语言:javascript
复制
                  read (ms)     write (ms)
PickleManager     9.26          7.92 
ShelveManager     5.32          30.9 

因此,看起来ShelveManager在读取方面可能更快,但PickleManager在写入方面可能更快。

请确保您自己运行这些测试。Timeit结果可能会因Python版本、操作系统、文件系统类型、硬件等而有所不同。

另外,请注意我的writeread函数会生成非常小的文件。您将希望在更类似于您的用例的数据上测试这一点。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4060937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档