带线程的基本 Mapreduce 比顺序版本慢

Basic Mapreduce with threads is slower than sequential version

我正在尝试使用线程对 mapreduce 进行单词计数,但此版本比顺序版本慢得多。对于一个 300MB 的文本文件,mapreduce 版本大约需要 80 秒,而顺序版本则需要更少的时间。我的问题是因为不明白为什么,因为我已经完成了 map reduce 的所有阶段(拆分、映射、洗牌、减少),但我不知道为什么它变慢了,因为我使用了大约 6 个线程来完成测试。我在想,与执行时间相比,线程的创建可能是昂贵的,但由于它需要大约 80 秒,我认为很明显这不是问题所在。你能看一下代码看看它是什么吗?我很确定代码工作正常,问题是我不知道是什么导致了缓慢。 最后一点,当使用超过300MB的文本文件时,程序会占满我电脑的所有内存,有什么办法可以优化吗?

首先声明几个免责声明:

  1. 要了解应用程序运行缓慢的确切原因,您需要对其进行分析。在这个答案中,我给出了一些常识推理。
  2. 我假设您使用的是 cPython

当您并行化某些算法时,有几个因素会影响性能。其中一些有利于速度(我用 + 标记它们)而有些则反对(-)。让我们看看它们:

  1. 你需要先拆分工作(-)
  2. work is parallel workers is simultaneously (+)
  3. 并行工作者可能需要同步他们的工作 (-)
  4. 减少所需时间 (-)

与顺序算法相比,为了让并行算法给您带来一些收益,您需要所有加速事情的因素超过所有拖累您的因素。

此外,与顺序处理相比,#2 的收益应该足够大以补偿您需要做的额外工作(这意味着对于某些 small 数据,您不会获得任何开销提升协调性会更大)。

现在实施中的主要问题是第 2 项和第 3 项。

首先,所有的工人都没有并行工作。您并行化的任务部分是 CPU 绑定的。在 python 中,单个进程的线程不能使用多个 CPU。所以在这个程序中它们永远不会并行执行。他们有相同的 CPU.

此外,他们对字典所做的每个修改操作都使用 locking/unlocking,这比不需要这种同步的顺序版本慢得多。

要加快您的算法,您需要:

  1. 使用多处理而不是多线程(这样你就可以使用多个CPU进行处理)
  2. 以一种不需要工人在工作时同步的方式构建算法(每个工人应该使用自己的字典来存储中间结果)