Многопроцессорный код Python работает медленнее однопоточного - PullRequest
1 голос
/ 30 мая 2019

Производительность Python Multiprocessing на моем i7 7700HQ значительно ниже, чем на непараллельном.

Планируя распараллелить мой код Select и Update для моей базы данных с одной таблицей в mssql, я попытался сначала распараллелить простоекод.Программа просто печатает кратные значения аргумента.Я пробовал однопоточный, многопроцессный с объектом Process, а также с объектом Pool.Однопотоковый всегда выполнялся лучше всего.

import time

def foobar(a):
    for i in range(1,10000):
        print(a*i)
    return
if __name__ == "__main__":
   Tthreading = time.clock()
    p1= Process(target= foobar, args=(3,))
    p2 = Process(target= foobar, args= (2,))
    p3 = Process(target= foobar, args= (4,))
    p4 = Process(target=foobar, args=(123,))

    allprocess.start

    allprocess.join

    print(time.clock() - Tthreading)

    #Single-threaded
    Tsingle = time.clock()
    foobar(3)
    foobar(2)
    foobar(4)
    foobar(123)
    print(time.clock() - Tsingle)


Я ожидал, что многопроцессорность будет намного быстрее, поскольку нет общих ресурсов (нет функций, переменных, к которым нужно обращаться между потоками) и IPC.

Однопотоковое время: 0,32 с

Время многопроцессорной обработки: 0,53 с

1 Ответ

2 голосов
/ 30 мая 2019

На самом деле, в вашем примере есть один важный общий ресурс - ваш монитор (или stdout).

print - это относительно медленная операция (по сравнению с циклами ЦП ...), и онавызывает конфликты между вашими процессами.

Сравнительный анализ правильности параллельной работы - сложная задача, на нее влияют многие факторы и характеристики процессора (например, кеша).

Попробуйте заменить свою рабочую нагрузку.с одним, который очень подходит для многопроцессорной обработки (например, параллельная работа над различными частями массива, умножение матриц ...)

Еще одна важная вещь: порождение новых процессов также требует времени, и для этого нужноОкупаемость работы, проделанной в каждом процессе, должна быть значительной.Если вы немного увеличите диапазон вашего цикла, разница должна быть в пользу многопроцессной версии:

import time
from multiprocessing import Process

def foobar(a):
    for i in range(1,10000000):
        a*i
    return

if __name__ == "__main__":
    Tthreading = time.time()
    p1= Process(target= foobar, args=(3,))
    p2 = Process(target= foobar, args= (2,))
    p3 = Process(target= foobar, args= (4,))
    p4 = Process(target=foobar, args=(123,))

    allprocess = [p1,p2,p3,p4]
    for p in allprocess:
        p.start()

    for p in allprocess:
        p.join()

    print(time.time() - Tthreading)

    #Single-threaded
    Tsingle = time.time()
    foobar(3)
    foobar(2)
    foobar(4)
    foobar(123)
    print(time.time() - Tsingle)

на моей машине это выдает:

0.44509196281433105

1,3775699138641357

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...