字典大小和内存消耗之间的平衡

时间:2014-04-14 23:37:52

标签: python algorithm memory data-structures dictionary

我使用memoized decorator来缓存重复的呼叫。由于在一些中等规模的测试用例上进行了记忆,我看到了4倍的执行速度。

对于较大的测试用例,记忆字典映射输入到输出会占用大量内存,直到我得到"java.lang.OutOfMemoryError: Java heap space"错误(我使用Jython)。< / p>

我可以使用memoized_cache[hash(key)] = value而不是memoized_cache[key]: value来节省一些内存,假设hash(key)的字节数少于key。正如@gnibbler所指出的,如果存在哈希冲突,这将导致问题。

我可以介绍的其他内存节省是将字典的大小限制为固定数量的项目。这样的SizedDict recipe已经存在,但我想截断最少访问的元素。

这是我写的:

from collections import Counter

class FrequencySizedDict(dict):
    def __init__(self, size=1000):
        dict.__init__(self)
        self._maxsize = size
        self._counter = Counter()
    def __getitem__(self, key):
        self._counter[key] += 1
        return dict.__getitem__(self, key)
    def resize(self, size):
        keys = list(self._counter.most_common(size))
        items = [(key, dict.__getitem__(self, key)) for key in keys]
        self.clear()
        dict.update(self, items)
    def __setitem__(self, key, value):
        if len(self._queue) >= self._maxsize:
            self.resize(self._maxsize/2)
        self._counter[key] += 1
        dict.__setitem__(self, key, value)

有更好的数据方式来实现这一点,内存或时间开销更少吗? resize非常昂贵:O(n log n)

1 个答案:

答案 0 :(得分:2)

使用functools.lru_cache

  

@ functools.lru_cache(maxsize = 128,typed = False)

     

Decorator用一个memoizing callable来包装一个函数,该函数可以保存maxsize最近的调用。当使用相同的参数定期调用昂贵的或I / O绑定函数时,它可以节省时间。

pylru,如答案memoization library for python 2.7

中所述