【发布时间】:2011-09-07 07:53:47
【问题描述】:
这个问题已经被问过很多次了。在花了一些时间阅读答案后,我做了一些快速分析以尝试前面提到的各种方法......
- 我有一个 600 MB 文件,其中包含 600 万 行字符串(来自 DMOZ 项目的类别路径)。
- 每一行的条目都是唯一的。
- 我想加载文件一次并继续搜索数据中的匹配项
我在下面尝试的三种方法列出了加载文件所用的时间、否定匹配的搜索时间和任务管理器中的内存使用情况
1) set :
(i) data = set(f.read().splitlines())
(ii) result = search_str in data
加载时间~10s,搜索时间~0.0s,内存使用~1.2GB
2) list :
(i) data = f.read().splitlines()
(ii) result = search_str in data
加载时间 ~ 6s,搜索时间 ~ 0.36s,内存使用 ~ 1.2GB
3) mmap :
(i) data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
(ii) result = data.find(search_str)
加载时间 ~ 0s,搜索时间 ~ 5.4s,内存使用 ~ NA
4) Hash lookup (using code from @alienhard below):
加载时间 ~ 65s,搜索时间 ~ 0.0s,内存使用 ~ 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
加载时间 ~ 0s,搜索时间 ~ 3.2s,内存使用 ~ NA
6) sqlite (with primary index on url):
加载时间 ~ 0s,搜索时间 ~ 0.0s,内存使用 ~ NA
对于我的用例,只要我有足够的可用内存,似乎使用 set 是最好的选择。我希望在这些问题上得到一些 cmets:
- 更好的选择,例如sqlite ?
- 使用 mmap 改进搜索时间的方法。我有一个 64 位的设置。 [编辑] 例如布隆过滤器
- 随着文件大小增长到几 GB,有什么方法可以让我继续使用“设置”,例如分批拆分..
[编辑 1]我需要经常搜索,添加/删除值,并且不能单独使用哈希表,因为我需要稍后检索修改后的值。
欢迎任何 cmets/建议!
[编辑 2] 使用答案中建议的方法的结果进行更新 [编辑 3] 使用 sqlite 结果更新
解决方案:基于所有的分析和反馈,我想我会选择 sqlite。第二种选择是方法 4。 sqlite 的一个缺点是数据库大小是带有 url 的原始 csv 文件的两倍多。这是由于 url 上的主索引
【问题讨论】:
-
您需要在文件中查找多个字符串,还是只查找一个字符串、一次或其他?
-
@senderle No. @EOL : 我需要反复搜索字符串,并添加新的.. 我会更新原帖
-
为什么选项1和2的内存使用一样?我尝试了一个大约 110k 行的 2.7mb 数据文件。列表的成本与数据文件的大小大致相同,而设置的对象的成本约为 4.1mb
标签: python performance search profiling large-files