这个问题已经被问了很多次。在阅读了答案后,我进行了一些快速分析来尝试之前提到的各种方法...
- 我有一个包含6百万行字符串(DMOZ项目的分类路径)的600 MB文件。
- 每行上的条目都是唯一的。
- 我想要一次加载该文件,并在数据中保持搜索以查找匹配项。
我尝试的三种方法如下,列出了加载文件所花费的时间、搜索负匹配所花费的时间和任务管理器中的内存使用情况:
1) set :
(i) data = set(f.read().splitlines())
(ii) result = search_str in data
加载时间约为10秒,搜索时间约为0.0秒,内存使用量约为1.2GB
2) list :
(i) data = f.read().splitlines()
(ii) result = search_str in data
加载时间约为6秒,搜索时间约为0.36秒,内存使用量约为1.2GB
3) mmap :
(i) data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
(ii) result = data.find(search_str)
加载时间约为0秒,搜索时间约为5.4秒,内存使用情况无法确定
4) Hash lookup (using code from @alienhard below):
加载时间 ~ 65秒,搜索时间 ~ 0.0秒,内存使用 ~ 250MB
5) File search (using code from @EOL below):
with open('input.txt') as f:
print search_str in f #search_str ends with the ('\n' or '\r\n') as in the file
加载时间约为0秒,搜索时间约为3.2秒,内存使用情况未知
6) sqlite (with primary index on url):
加载时间 ~ 0秒,搜索时间 ~ 0.0秒,内存使用 ~ NA
对于我的用例而言,只要我有足够的内存可用,选择使用 set 看起来是最好的选项。我希望对以下问题提出一些评论:
- 更好的替代方案,例如 sqlite?
- 使用 mmap 改进搜索时间的方法。我有一个64位设置。 [编辑] 例如布隆过滤器
- 当文件大小增长到几个GB时,是否有任何方法可以继续使用 'set',例如将其分批处理..
[编辑1] P.S. 我需要频繁搜索、添加/删除值,并且不能仅使用哈希表,因为我需要稍后检索修改后的值。
欢迎提出任何评论或建议!
[编辑2] 使用答案中建议的方法更新结果 [编辑3] 使用sqlite的结果更新
解决方案: 基于所有的分析和反馈,我认为我会选择使用 sqlite。第二种选择是方法4。 sqlite的一个缺点是数据库大小超过了具有url的原始csv文件的两倍。这是由于url上的主索引造成的。