从磁盘读取列表比加载字典更好吗?

时间:2009-05-21 22:12:17

标签: python list dictionary performance

我正在构建一个应用程序,我试图允许用户提交公司和日期对列表,并查明该日期是否有新闻事件。新闻事件存储在具有公司标识符和日期作为关键字的字典中。

newsDict('identifier','MM/DD/YYYY')=[list of news events for that date]

字典比我想象的要大得多 - 甚至在内存中构建它太大了所以我将其分解为三个部分,每个部分仅限于特定范围的公司标识符。

我的计划是获取用户提交的列表并使用字典组公司标识符的用户列表来匹配预期将找到公司事件的特定newsDict,然后一个接一个地加载newsDicts以获取值

现在我想知道将新闻事件保存在列表中是不是更好,列表中的每个项目都是元组和另一个列表的子列表列表

[('identifier','MM/DD/YYYY'),[list of news events for that date]]

我的想法是,我会有一个字典,其中包含每个公司标识符的列表范围

 companyDict['identifier']=(begofRangeinListforComp,endofRangeinListforComp)

我会使用用户输入查找我需要的范围,并构建按范围排序的标识符和范围列表。然后我会阅读列表的相应部分以获取数据并构造输出。

我看到的最大原因是,即使将字典分成三部分,每个部分大约需要两分钟才能加载到我的机器上,字典最终会占用大约600到750 MB的内存。

我很惊讶地注意到,一个包含800万行的列表只需要大约15秒的时间来加载并使用大约1/3的字典内存的1/3。

此外,由于我在列表中工作时可以丢弃列表中的行,因此当我处理用户列表时,我将释放内存。

我很惊讶,因为我认为字典是最有效的方法。但是我的嘲笑表明字典需要比列表更多的内存。我在SO和其他地方阅读其他帖子表明,任何其他结构都需要比列表指针更昂贵的指针分配。我在这里遗漏了什么,有更好的方法吗?

在阅读了Alberto的回答并回复我的评论后,我花了一些时间试图弄清楚如果我要使用数据库如何编写该函数。现在我可能会陷入困境,因为我对db编程知之甚少,但

我认为使用数据库实现的代码要比:

复杂得多
outList=[]
massiveFile=open('theFile','r')
for identifier in sortedUserList
# I get the list and sort it by the key of the dictionary 
    identifierList=massiveFile[theDict[identifier]['beginPosit']:theDict[identifier]['endPosit']+1]
    for item in identifierList:
        if item.startswith(manipulation of the identifier)
        outList.append(item)

我必须将它包装在一个函数中,如果我将列表转换为db,我没有看到任何相对简单的函数。

当然,更简单的不是将我带到这个论坛的原因。我仍然没有看到使用其他结构将花费更少的内存。我有30000个公司标识符和大约3600个日期。我列表中的每个项目都是OOD用语中的对象。这就是我在挣扎的地方,今天早上我花了六个小时来组织字典的数据,然后才放弃。花费一定的时间来实现一个数据库,然后发现我正在使用半个或更多别人的内存加载它似乎有问题

2 个答案:

答案 0 :(得分:5)

如此大量的数据,您应该使用数据库。这比查看列表要好得多,并且无论如何都是最合适的存储数据的方式。如果您使用的是Python,我相信它内置了SQLite。

答案 1 :(得分:1)

字典会占用更多内存,因为它实际上是一个哈希值。

您不必使用数据库,因为您的查找要求非常简单。只需使用文件系统。

根据公司名称(或自动收报机)创建目录结构,并为每个日期指定子目录。要查找数据是否存在并加载,只需形成数据所在子目录的名称,并查看它是否存在。

例如,5月21日的IBM新闻将在C:\ db \ IBM \ 20090521 \ news.txt中,如果事实上当天有新闻。你只需检查文件是否存在;没有搜索。

如果您想尝试从那里提高速度,请提出一个方案来缓存可能经常请求的有限数量的结果(假设您正在运行服务器)。为此,你要使用哈希。