【发布时间】:2013-04-27 23:20:55
【问题描述】:
我有一个 20 GB 的大文本文件。该文件包含相对较短的文本行(每行 40 到 60 个字符)。文件未排序。
我有一个包含 20,000 个唯一字符串的列表。我想知道每个字符串每次出现在文件中时的偏移量。目前,我的输出如下所示:
netloader.cc found at offset: 46350917
netloader.cc found at offset: 48138591
netloader.cc found at offset: 50012089
netloader.cc found at offset: 51622874
netloader.cc found at offset: 52588949
...
360doc.com found at offset: 26411474
360doc.com found at offset: 26411508
360doc.com found at offset: 26483662
360doc.com found at offset: 26582000
我将 20,000 个字符串加载到 std::set 中(以确保唯一性),然后从文件中读取 128MB 块,然后使用 string::find 搜索字符串(通过读取另一个 128MB 块重新开始)。这工作并在大约 4 天内完成。我不担心读取边界可能会破坏我正在搜索的字符串。如果是这样,那没关系。
我想让它更快。在 1 天内完成搜索将是理想的,但任何显着的性能改进都会很好。我更喜欢将标准 C++ 与 Boost(如果需要)一起使用,同时避免使用其他库。
所以我有两个问题:
- 考虑到我使用的工具和任务,4 天的时间是否合理?
- 加快速度的最佳方法是什么?
谢谢。
编辑:使用 Trie 解决方案,我能够将运行时间缩短到 27 小时。不是一天之内,但现在肯定要快得多。谢谢你的建议。
【问题讨论】:
-
这些字符串是否看起来像单个单词或标识符,而不是整个句子,用空格等分隔?
-
您是否尝试过分析您的代码?它是否花费更多时间从输入文件中搜索或读取?
-
读取 20Gb 不能花 4 天...
-
@piokuc,你说得对,但我认为他正在读取 20,000 次,意味着总共读取了大约 390TB。我的建议是,如果已知可用 RAM,则将文件拆分为相当大的块,在每个块中搜索字符串,转储块,然后继续。不过,他检查字符串的方法有很大的不同。
-
他说他正在读取 128MB 块并在一个块中进行 20k 次搜索,然后再转到下一个块,这就是我的理解。
标签: c++ string performance