阅读一个大文件来计算重复K次的单词数
Read a big file to count the number of words repeat K times
问题
有一个大文件(10GB),必须读取文件并打印出文件中重复k
次的字数
我的解决方案
- 使用
ifstream
逐字阅读文件; - 将单词插入到地图
std::map<std::string, long> mp; mp[word] += 1;
- 读取文件后,找到地图中的所有单词以获取出现
k
次数的单词
问题
- 如何使用多线程有效地读取文件[按块读取]?或 任何提高读取速度的方法。
- 除了map之外,是否有更好的数据结构可以有效地找到输出?
文件信息
- 每行最长可达500字
- 每个单词的最大长度为 100 个字符
如何使用多线程有效地读取文件[按块读取]?或 任何提高读取速度的方法。
我一直在尝试实际结果,与我之前的建议不同,多线程是一件好事。非线程变体以 1m44,711s 运行,4 线程变体(在 4 个内核上)以 0m31,559s 运行,8 线程变体(在 4 个内核 + HT 上运行)在 0m23,435s 运行。然后进行重大改进 - 加速几乎是 5 倍。
那么,如何分配工作量呢?将其拆分为 N 个块(n == 线程计数),并让每个线程(第一个线程除外)首先查找第一个非单词字符。这是他们逻辑块的开始。它们的逻辑块在其结束边界处结束,在此点之后四舍五入到第一个非单词字符。
并行处理这些块,将它们全部同步到一个线程,然后使该线程合并结果。
要提高读取速度,接下来最好的事情就是确保尽可能不复制数据。通读内存映射文件,并通过保留指向开头和结尾的指针或索引来查找字符串,而不是累积字节。
除了map之外,是否有更好的数据结构可以有效地找到输出?
好吧,因为我认为您不会使用该订单,所以unordered_map是更好的选择。我也会把它变成一个unordered_map<std::string_view, size_t>
- string_view复制它甚至比字符串更少。
在分析时,我发现 53% 的时间都花在查找包含给定单词的确切存储桶上。
如果你有一个64位系统,那么你可以对文件进行内存映射,并使用例如这个解决方案从内存中读取。
结合 dascandy 关于std::unordered_map
和std::string_view
的答案(如果有的话),您应该尽可能快地在单个线程中获得。你可以用std::unordered_multiset
而不是std::unordered_map
,我不知道哪一个"更快"。
使用线程很简单,只需执行您所知道的操作,但每个线程仅处理文件的一部分。在所有线程完成后合并映射。但是,当您为每个线程将文件拆分为块时,您可能会在中间拆分单词。处理这个问题并非易事。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 如何打印以特定字符开头的单词数?
- 将输入作为C 中的单词数组
- 阅读一个大文件来计算重复K次的单词数
- C++ 查找其中字母最少的单词数
- 我的逻辑有什么问题?尝试计算文件中包含特定字符的单词数
- 我需要在接受用户输入后返回 c 刺痛中的单词数
- 计算字符串中的单词数,C++
- 如何输入单词数组c++
- 计算字符数组C++中的单词数
- c++计算一行中的单词数
- 在C++中计算单通道直方图的平均值和标准偏差
- 如何通过检查v. dictionary来查找一个短语中删除空格的单词数
- 函数定义计算单词数
- 我如何检索点的单应性计算findHomography和RANSAC
- 如何在列表中找到单词数
- 如何获得字符串中的单词数