Мне нужно создать итератор объекта, который принимает входные данные range
и применяет некоторые операции, чтобы создать итератор простых чисел.Затем мне нужно передать этот простой итератор некоторому методу multiprocessing
(возможно, imap
?), Чтобы простые числа вычислялись с использованием параллельной обработки только при вызове объектного итератора.Это мой MWE:
import multiprocessing as mp
from itertools import islice
class PrimeIterator:
"""Iterator class"""
def __init__(self, input_stream, *, number_of_processes=mp.cpu_count()):
"""Initiate object"""
self.input = input_stream
self.pool = mp.Pool(number_of_processes)
def __iter__(self):
"""Return iterator"""
self.iterator = map(is_prime, self.input)
pool_iterator = self.pool.imap_unordered(pass_to_mp, self.iterator)
return pool_iterator
def __next__(self):
"""Return next item from iterator"""
try:
return next(pool_iterator)
except StopIteration:
return
def pass_to_mp(value):
time.sleep(.4)
return value
def is_prime(n):
if n < 2:
return False, n
elif n == 2:
return True, n
sqrt_n = int(n**0.5)+1
return len([i for i in range(2, sqrt_n+1) if n % i == 0]) == 0, n
PrimeIterator
можно проверить следующим образом:
list(islice(PrimeIterator(range(100), number_of_processes=10), 10))
и это вывод:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Несмотря на то, что яполучить правильные данные, время работы довольно долго.Есть ли более эффективная multiprocesing
реализация данной задачи?