Когда я запускаю код без lru_cache
, я получаю этот результат. Что понятно
с мультипроцессором
время заняло 0.4375
без многопроцессорности
время заняло8.8125
Но когда я запускаю с помощью lru_cache
, вот результат:
Тест1
с мультипроцессором
время заняло 0.34375
без многопроцессорности
время заняло 0.3125
Тест2
с мультипроцессором
времени ушло 3.234375
без многопроцессорности
время заняло 3.046875
Мы можем ясно видеть, что без многопроцессорности он почти равен или немного быстрее, чем многопроцессорный метод. В чем причина этого? Я понимаю, что процесс создания является накладным, но список работ очень велик (10 миллионов), поэтому я думаю, что размер фрагмента не слишком мал. Или я делаю это неправильно?
Объяснение кода:
odlist() берет число и возвращает сумму всех нечетных чисел в этом диапазоне
odcount — это кортеж, содержащий 10 миллионов случайных чисел.
Код:
import os
from random import randint
from functools import reduce
from operator import add
from multiprocessing import Pool
import time
from functools import lru_cache
@lru_cache(maxsize=None)
def oddlist(num):
return reduce(add,(i for i in range(num) if i&1))
if __name__ == '__main__':
oddcounts=tuple(randint(10,50) for i in range(10000000))
print('with multiporcessing')
s=time.process_time()
with Pool(12) as p:
mp=p.map(oddlist, oddcounts)
e=time.process_time()
print(f'time took {e-s}')
print('witout multiporcessing')
s=time.process_time()
z=tuple(oddlist(i) for i in oddcounts)
e=time.process_time()
print(f'time took {e-s}')
@Клаус Д. Разве каждый из них не получает около 833 333 чисел от 10 до 50, так что все равно получит 99,995% попаданий в кеш?
Кстати, reduce(add, whatever)
-> sum(whatever)
. действительно, reduce
довольно антиидиоматичен, но, по крайней мере, не используйте его, чтобы заново изобретать велосипед
Кроме того, пожалуйста, всегда предоставляйте минимальный воспроизводимый пример. Мы должны иметь возможность скопировать и вставить ваш код и запустить его.
Каждый процесс имеет свой собственный кэш, поэтому при использовании многопроцессорной обработки кэширование на 1/12 эффективнее, чем в противном случае. Есть только 40 возможных входных значений в нечетный список. В случае многопроцессорности каждый процесс вычисляет все 40, а затем использует кеш. Без многопроцессорности все 40 вычисляются только один раз. Таким образом, в дополнение к накладным расходам на запуск процессов, каждый процесс выполняет больше работы, чем необходимо, если бы кэширование работало должным образом. Кроме того, есть затраты на передачу ему работы, которую необходимо выполнить в каждом процессе, и передачу результата обратно.
Каждый процесс будет иметь свой собственный кеш, что сделает кеширование менее эффективным.