Почему пул и кешированный метод имеют почти одинаковое время выполнения?

Когда я запускаю код без 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}')

Каждый процесс будет иметь свой собственный кеш, что сделает кеширование менее эффективным.

Klaus D. 11.12.2020 06:11

@Клаус Д. Разве каждый из них не получает около 833 333 чисел от 10 до 50, так что все равно получит 99,995% попаданий в кеш?

Kelly Bundy 11.12.2020 06:26

Кстати, reduce(add, whatever) -> sum(whatever). действительно, reduce довольно антиидиоматичен, но, по крайней мере, не используйте его, чтобы заново изобретать велосипед

juanpa.arrivillaga 11.12.2020 06:38

Кроме того, пожалуйста, всегда предоставляйте минимальный воспроизводимый пример. Мы должны иметь возможность скопировать и вставить ваш код и запустить его.

juanpa.arrivillaga 11.12.2020 06:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Каждый процесс имеет свой собственный кэш, поэтому при использовании многопроцессорной обработки кэширование на 1/12 эффективнее, чем в противном случае. Есть только 40 возможных входных значений в нечетный список. В случае многопроцессорности каждый процесс вычисляет все 40, а затем использует кеш. Без многопроцессорности все 40 вычисляются только один раз. Таким образом, в дополнение к накладным расходам на запуск процессов, каждый процесс выполняет больше работы, чем необходимо, если бы кэширование работало должным образом. Кроме того, есть затраты на передачу ему работы, которую необходимо выполнить в каждом процессе, и передачу результата обратно.

Другие вопросы по теме