为什么多处理很慢

时间:2014-06-24 00:07:07

标签: python performance python-2.7 multiprocessing primes

我刚开始阅读有关多处理的内容,以加快我的程序速度。 因此,我写了两个基本的例子来从随机数列表中提取素数。

示例1:使用多处理

from multiprocessing import Process, Queue
from random import randrange
import time

def randomList(q, size, nmax):
    l = []
    r = randrange(2, nmax)
    for i in range(size):
        while r in l: # avoid replicating numbers
            r = randrange(2, nmax)
        l.append(r)
        q.put(r)

def checkPrime(numbers, prime):
    if numbers.qsize():
        n = numbers.get()
        count = 0 # divisors counter
        d = 2 # divisor
        while not count and d<=n/2:
            if n%d:
                d+=1
            else:
                count+=1
        if not count:
            prime.put(n)

if __name__=="__main__":
    numbers = Queue()
    prime = Queue()
    randomList(numbers, 50, 1000) # 50 number | 100 max value
    t1 = time.time()
    while numbers.qsize():
        for i in range(10): # Running 10 processes 
            p=Process(target=checkPrime, args=(numbers, prime))
            p.start()
            p.join()
    t2 = time.time()
    primes = []
    for i in range(prime.qsize()):
        primes.append(prime.get())
    print("[+] Prime numbers:")
    print(primes)
    print("[+] Time elapsed:"+str(t2-t1))

输出:

[+] Prime numbers:
[17, 227, 389, 593, 953, 757]
[+] Time elapsed:9.41699981689

例2:相同的例子1但没有多处理

[...]
    while numbers.qsize():
        checkPrime(numbers, prime)
[...]

输出:

[+] Prime numbers:
[193, 227, 241, 439, 499, 877, 479, 743, 929]
[+] Time elapsed:0.00999999046326

因此,多处理使得这个程序(特别是可能)比没有使用它的速度慢很多。 任何解释?我用错了方法吗?

3 个答案:

答案 0 :(得分:3)

我在想你的多处理方法很差。您不是将工作分成10个流程并立即启动它们,而是一次启动一个流程,每个流程都在执行单个工作单元,然后退出。您的实现将在其生命周期内创建(然后销毁)50个进程,这会产生大量开销。

您也可以在启动它们后立即加入这些流程,这将使您从未实际运行多个流程。连接使它等待子进程完成后再继续。

最后,还有一种更好的方法可以返回使用队列并一次获取单个值的结果。如果您可以使用一组工作立即启动每个进程,然后将列表中的结果返回到主线程,则可以减少使用队列的开销。

答案 1 :(得分:1)

for i in range() .join()时,.join()正在等待整个过程完成。因此,基本上,您正在生成一个新进程,该进程使用队列并报告结果,然后生成其他9个进程来检查空队列。

<强> map_async()

  

阻止调用线程,直到调用join()方法的进程终止或者直到发生可选超时为止。

池是一种更简单的方法来做同样的事情。 检查此答案是否将{{1}}与工作人员一起使用:

Python Multiprocessing map_async

答案 2 :(得分:1)

多处理中有一个简单的规则:如果用于分割(创建子任务)+加入(连接结果等)以创建多处理&gt;顺序时间然后你的“并行”版本相对于顺序版本将是低效的。这是你的情况。尝试生成一百万个数字(保持10个进程数),您将看到差异。

@ Sohcahtoa82的良好编码技巧。记住它们。