【问题标题】:Python filter massive iterator with multiprocessingPython过滤具有多处理的大规模迭代器
【发布时间】:2021-11-11 16:13:28
【问题描述】:

这是我在使用多处理之前的代码。获取大量迭代器中满足指定条件的项目数是一项任务:

from itertools import permutations

def f(input_):
    if 'AB' in ''.join(input_):
        return True
    else:
        return False

if __name__ == "__main__":
    iterator = permutations(['A', 'B',...])
    count = 0
    for item in iterator:  # it is an itertools.permutations object, with str inside
        if f(item):
            count += 1
    print(count)

但是迭代器太大了,我需要做多处理或多线程(不确定哪个更好)来加快进程。

我参考了很多关于 Python 中多任务的在线参考资料,并尝试了几种方法。不幸的是,我仍然找不到解决方案,因为我尝试的每种方法都有一些问题。 例如:

from multiprocessing import Pool

def f(input_):
    if 'AB' in ''.join(input_):
        return True
    else:
        return False

if __name__ == "__main__":
    pool = Pool()
    result = pool.imap_unordered(f, iterator)
    print(sum(result))

在这个例子中,问题是这段代码的运行速度比我原来的还要慢。我也尝试过使用 pool.map(),但它也比以前慢了,而且它耗尽了我所有的内存。

我应该如何使用我所有的 CPU 能力尽可能快地完成这个过滤任务?多处理和多线程真的让我很困惑。 :(

【问题讨论】:

  • 在不知道迭代器做什么的情况下,不可能说出如何处理这个问题。多线程/处理有其自身的开销,如果迭代器进行磁盘 I/O,并行化将没有用处。
  • 我建议通过将原始代码压缩为count = sum(map(f, iterator)) 来消除不必要的开销。不会更改 big-O,但会消除一些不必要的开销(此外,作为微优化,如果 f 返回 1/0 而不是 True/@,sum 的快速路径会更好地工作987654329@)。也就是说,任何真正的节省都取决于了解f 是如何实现的。
  • @MadPhysicist 迭代器的类型是itertools.permutations。这是字符串的排列。如['A', 'B', 'C']的排列,校验条件如if 'AB' in ''.join(input_)
  • 如果我理解你的描述,这是一个可以非常清楚地在 O(1) 时间内解决的问题。
  • 抱歉信息不足,我已经更新了问题。

标签: python python-3.x multithreading multiprocessing


【解决方案1】:

itertools.permutations 相比,多处理具有巨大的开销。同时,几乎所有与排列有关的问题都可以使用简单的阶乘来解决。

你的“巨大”迭代器可以写成

data = ['A', 'B', 'C', ...]
pattern = ('A', 'B')
sum(pattern in x for x in permutations(data))

话虽如此,有factorial(len(data)) 可能的总排列。如果data没有重复,那么除了patternlen(data) - len(pattern) + 1可以存在pattern的地方之外,还有factorial(len(data) - len(pattern))可能的项目安排。

从 python 3.8 开始,您可以这样做

from math import prod

count = prod(range(2, len(data) - len(pattern) + 2))

对于以前的版本,您必须这样做

from functools import reduce
from operator import mul

count = reduce(mul, range(2, len(data) - len(pattern) + 2), 1)

对于data 的重复出现在pattern 中的情况,您可以在 Google 上搜索“有多少排列将包含特定序列”之类的内容,以帮助您找出分析公式。

【讨论】:

  • 我明白了!我曾经认为并行化始终是加速重复任务的最佳方式。那么,对于这类问题(反复做会员算子),多核cpu不能带来什么好处?
  • 之所以使用穷举法,是为了验证一些复杂排列的解析式。虽然验证方式效率不高,但我想尽可能地利用我电脑的性能来获得最短的时间。
  • @HuiGordon。数学证明不如筛选大量数据吗?
  • 哦,我不是这个意思。只是在数学证明之外尝试一些其他方法,因为枚举更直接。如果对于这种重复工作,使用单线程已经是最快的,我会接受的。谢谢!
  • 如果你想走得快,就不要用python。置换很容易用 C 语言实现。而且很容易将外循环分成块以进行多线程或多处理。
猜你喜欢
  • 2020-05-27
  • 2020-08-09
  • 2020-02-19
  • 2017-11-17
  • 2011-04-25
  • 1970-01-01
  • 2015-10-04
  • 1970-01-01
  • 2012-04-16
相关资源
最近更新 更多