首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中昂贵对象的智能缓存

Python中昂贵对象的智能缓存
EN

Stack Overflow用户
提问于 2012-01-03 15:14:47
回答 2查看 3.9K关注 0票数 1

我有一个按顺序排列的图像目录。通常,我的代码将使用序列图像子集中的数据(例如,图像5-10),访问这些图像的简单选项如下:

  1. 使用一个方法创建一个包装器对象,该方法在需要时加载图像并读取我的数据(例如像素值)。这有很小的内存开销,但速度很慢,因为每次都需要加载每个映像。
  2. 将所有图像存储在内存中。这将是快速的,但很明显,我们可以存储多少图像是有限度的。

我想找到:

  • 某种方法,我可以通过它定义如何读取与索引或路径相对应的图像,然后允许我访问,比如magic_image_collection[index],而不必担心它是否会返回内存中的对象或重新读取它。理想情况下,这将在内存中保留适当的映像或n最近访问的图像。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-03 15:33:10

如果缺少键,可以扩展默认的dict,并使用__missing__方法调用加载函数:

代码语言:javascript
复制
class ImageDict(dict):
    def __missing__(self, key):
        self[key] = img = self.load(key)
        return img
    def load(self, key):
        # create a queue if not exist (could be moved to __init__)
        if not hasattr(self, '_queue'):
            self._queue = []
        # pop the oldest entry in the list and the dict
        if len(self._queue) >= 100:
            self.pop(self._queue.pop(0))
        # append this key as a newest entry in the queue
        self._queue.append(key)
        # implement image loading here and return the image instance
        print 'loading', key
        return 'Image for %s' % key

以及输出(只有在键还不存在时才会加载)。

代码语言:javascript
复制
>>> d = ImageDict()
>>> d[3]
loading 3
'Image for 3'
>>> d[3]
'Image for 3'
>>> d['bleh']
loading bleh
'Image for bleh'
>>> d['bleh']
'Image for bleh'

一种进化方法是只在dict中存储N个最后一个元素,并清除最古老的条目。您可以通过保留用于排序的键列表来实现它。

票数 5
EN

Stack Overflow用户

发布于 2012-01-03 15:25:36

弱引用不是你想要的--弱引用是一种引用一个项目的方法,它允许垃圾收集器收集(即销毁)参考文献,如果只是弱引用的话。换句话说,如果您只创建和存储某个对象的弱引用,那么它很可能很快就会被垃圾收集,而且您不会从中受益。

我会同意你上面的第一项选择。在现代操作系统上,操作系统维护一个最近访问的文件(或其部分)的内存缓存,这意味着您将不得不承担一次从磁盘加载文件的成本,但此后,对该文件的后续访问将与应用程序中内存中的文件一样快(或几乎如此)。FS缓存通常是LRU风格的缓存,因此频繁访问的项目往往留在内存中,而不频繁访问的项目往往会被逐出(如果需要,随后将从磁盘加载)。在大多数情况下,依赖于操作系统实现这类逻辑就足够了,而不是编写自己的逻辑(特别是因为您不需要编写和维护代码就可以做到这一点!)

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

https://stackoverflow.com/questions/8714358

复制
相关文章

相似问题

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