Улучшение скорости выполнения Python с параллельными потоками - PullRequest
0 голосов
/ 08 декабря 2011

Допустим, у меня есть этот пример кода:

x = foo1(something1)
y = foo2(something2)

z = max(x, y)

Я хочу улучшить время выполнения этого кода с помощью потоков (надеюсь, это поможет, не так ли?).Я хотел бы сделать вещи максимально простыми, поэтому в основном я хотел бы создать два потока, работающих одновременно, которые вычисляют соответственно foo1 и foo2.

Я читаюкое-что о потоках, но я нашел это немного хитрым, и я не могу терять слишком много времени только на то, чтобы делать такую ​​простую вещь.

Ответы [ 4 ]

8 голосов
/ 08 декабря 2011

Если предположить, что foo1 или foo2 привязано к процессору, многопоточность не увеличивает время выполнения ... фактически, обычно это ухудшает ... для получения дополнительной информации см. презентацию Дэвида Бизли на PyCon2010 на глобальном замке интерпретатора / Pycon2010 GIL слайды . Эта презентация очень информативна, я настоятельно рекомендую ее всем, кто пытается распределить нагрузку между ядрами процессора.

Лучший способ улучшить производительность - это многопроцессорный модуль

Предполагая, что между foo1() и foo2() не требуется общего состояния, сделайте это, чтобы улучшить производительность выполнения ...

from multiprocessing import Process, Queue
import time

def foo1(queue, arg1):
    # Measure execution time and return the total time in the queue
    print "Got arg1=%s" % arg1
    start = time.time()
    while (arg1 > 0):
        arg1 = arg1 - 1
        time.sleep(0.01)
    # return the output of the call through the Queue
    queue.put(time.time() - start)

def foo2(queue, arg1):
    foo1(queue, 2*arg1)

_start = time.time()
my_q1 = Queue()
my_q2 = Queue()

# The equivalent of x = foo1(50) in OP's code
p1 = Process(target=foo1, args=[my_q1, 50])
# The equivalent of y = foo2(50) in OP's code
p2 = Process(target=foo2, args=[my_q2, 50])

p1.start(); p2.start()
p1.join(); p2.join()
# Get return values from each Queue
x = my_q1.get()
y = my_q2.get()

print "RESULT", x, y
print "TOTAL EXECUTION TIME", (time.time() - _start)

На моей машине это приводит к:

mpenning@mpenning-T61:~$ python test.py 
Got arg1=100
Got arg1=50
RESULT 0.50578212738 1.01011300087
TOTAL EXECUTION TIME 1.02570295334
mpenning@mpenning-T61:~$ 
0 голосов
/ 08 декабря 2011

Вы можете использовать модуль python thread или новый модуль Threading, однако использование модуля thread проще в синтаксисе,

#!/usr/bin/python

import thread
import time

# Define a function for the thread
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print "%s: %s" % ( threadName, time.ctime(time.time()) )

# Create two threads as follows
try:
   thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print "Error: unable to start thread"

while 1:
   pass

выведет,

Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009

Подробнее читайте здесь, Python - многопоточное программирование

0 голосов
/ 08 декабря 2011

Сначала прочтите документацию здесь , чтобы понять код ниже:

import threading

def foo1(x=0):
    return pow(x, 2)

def foo2(y=0):
    return pow(y, 3)

thread1 = threading.Thread(target=foo1, args=(3))
thread2 = threading.Thread(target=foo2, args=(2))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
0 голосов
/ 08 декабря 2011

Это не поможет.Прочитайте FAQ по Python.

...