加载pickled python对象需要大量内存

2024-05-23 15:43:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python的pickled对象,它生成一个180mb的文件。当我解开它时,内存使用量会激增到2或3Gb。你有类似的经历吗?正常吗?

对象是包含字典的树:每条边都是一个字母,每个节点都是一个潜在的单词。所以要存储一个单词,你需要的边和这个单词的长度一样多。所以,第一层是最大26节点,第二层是26^2,第三层是26^3,等等。。。每个节点都是一个单词,我有一个指向单词信息的属性(动词、名词、定义等)。

我最多有40个字。我有大约50万条记录。一切都顺利,直到我pickle(使用一个简单的cpickle转储):它提供了一个180 Mb的文件。 我在Mac操作系统上,当我解开这些180mb时,操作系统会给python进程2或3gb的“内存/虚拟内存”:

我在这棵树上看不到任何递归:边上有自己的数组的节点。不涉及递归。

我有点困了:这180 Mb的加载大约是20秒(不谈内存问题)。我不得不说我的CPU没有那么快:核心i5,1.3Ghz。但我的硬盘是固态硬盘。我只有4Gb的内存。

为了在我的树中添加这50万个单词,我阅读了大约7000个文件,每个文件包含大约100个单词。这样的读取使得mac操作系统分配的内存达到15gb,主要是虚拟内存:(我一直在使用“with”语句来确保每个文件的关闭,但并没有真正的帮助。读取文件大约需要0.2秒40 Ko。对我来说似乎很长。将它添加到树中要快得多(0.002秒)。

最后,我想创建一个对象数据库,但我想python不适合这样做。也许我会去买一个MongoDB:

class Trie():
    """
    Class to store known entities / word / verbs...
    """
    longest_word  = -1
    nb_entree     = 0

    def __init__(self):
        self.children    = {}
        self.isWord      = False
        self.infos       =[]

    def add(self, orthographe, entree):  
        """
        Store a string with the given type and definition in the Trie structure.
        """
        if len(orthographe) >Trie.longest_word:
            Trie.longest_word = len(orthographe)

        if len(orthographe)==0:
            self.isWord = True
            self.infos.append(entree)
            Trie.nb_entree += 1
            return True

        car = orthographe[0]
        if car not in self.children.keys():
            self.children[car] = Trie()

        self.children[car].add(orthographe[1:], entree)

Tags: 文件对象内存selflenlongestif节点