首页 > 解决方案 > Python多处理比单处理慢

问题描述

排序.py

import random
import time

def time_analysis(func):
    def do_func(*args, **kwargs):
        print('[INFO] \'{}\' analysis started (N={}).'.format(func.__name__, len(args[0])))
        start_time = time.clock()
        result = func(*args, **kwargs)
        end_time = time.clock()
        total_time = end_time - start_time
        print('[INFO] \'{}\' took {} seconds (N={}).'.format(func.__name__, total_time, len(args[0])))
        return result

    return do_func


@time_analysis
def bubble_sort(num_list):
    num_len = len(num_list)
    for i in range(num_len - 1):
        for j in range(num_len - i - 1):
            if num_list[j] > num_list[j + 1]:
                num_list[j], num_list[j + 1] = num_list[j + 1], num_list[j]
    return num_list

if __name__ == '__main__':
    N = 30000
    random_list = list(range(N))
    random.shuffle(random_list)
    bubble_sort(random_list)

    random_list = list(range(N))
    random.shuffle(random_list)
    bubble_sort(random_list)

并行.py

from multiprocessing import Pool, cpu_count
from Sort import *

def bubble_sort_parallel(*args, **kwargs):
    return bubble_sort(*args, **kwargs)

if __name__ == '__main__':
    N = 30000
    random_list = list(range(N))
    random.shuffle(random_list)
    pool.apply_async(bubble_sort_parallel, (random_list,))
    random_list = list(range(N))
    random.shuffle(random_list)
    pool.apply_async(bubble_sort_parallel, (random_list,))

    pool.close()
    pool.join()

单线程只用了 2 秒,但多处理用了 8 秒。

N = 300,000。单线程只用了 200 秒,但多处理用了 1400 秒。

为什么使用多处理比单线程慢?

我怎样才能提高性能?

平台:Linux,pypy2.7-5.10.0,我的电脑4核

多处理:【多处理图】【https://i.stack.imgur.com/QksXf.png】

单线程:【单线程图】【https://i.stack.imgur.com/9HYw7.png】

标签: pythonconcurrencymultiprocessingpypy

解决方案


我希望您已经清楚这一点:Pool.apply_async允许您将工作分派给池中的其他进程;它不会自动并行化单个函数。换句话说,两个版本都在单个内核上的单个线程中执行每种排序。并行版本应该将两个排序调用分派到两个核心,但是您测量的是每个排序的运行时间,而不是整个程序的执行,因此您不会通过两个排序调用的重叠检测到任何节省。(此外,目前,您的代码不包括池对象的创建,所以我只是假设您使用processes=NN > 2 ——尽管如此,这并不重要,因为您没有测量整体运行时而是每种类型的运行时间。)

(如果没有,请参阅 https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workershttps://docs.python.org/2/library/multiprocessing.html #module-multiprocessing.pool

然而,这并不能解释为什么简单地将工作分派到另一个进程会导致运行时间变慢。(值得注意的是,在我的 MacBook Pro 上,简单版和“并行”版的执行时间没有区别。)速度慢的原因是进程之间的通信。您要求它通过其 IPC 通道传输一个大列表,而这样做显然效率不高。您可以自己演示一下:将列表创建和改组移动到空列表bubble_sort_parallel中,并将参数传递给提供的函数。pool.apply_async在我的计算机上,这使得运行时与基本版本相同。


推荐阅读