【Python】为什么多线程并行不快反慢?

项目场景

这里有个证件照换底的需求:将图像的透明底色换为红色背景。其逻辑是用一个嵌套的 for 循环分别遍历图像的行和列,判断每一个位置的像素点是否是透明的,如果是,换成红色背景;如果不是,则不做任何修改。但目前的问题是速度有点慢,需要做并行加速。我们用 Python 自带的多线程池进行优化,优化程序的代码如下:

"""安装依赖模块
pip install numpy opencv-python tqdm
"""
import time
import numpy as np
from cv2 import cv2
from tqdm import tqdm
import concurrent.futures as cf


class ChangeBackgroundColor():
    """修改图片背景的类(默认将透明背景修改为红色背景)

    Args:
        root (str): 输入图片的路径
    """
    def __init__(self, root: str):
        """类的初始化函数

        Args:
            root (str): 输入图片的路径
        """
        self.image_original = cv2.imread(root, cv2.IMREAD_UNCHANGED)
        self.rows, self.cols, _ = self.image_original.shape
        self.serial()
        self.parallel()

    def serial(self):
        """串行程序
        """
        t1 = time.time()
        for i in tqdm(range(self.rows), desc='Serial-Time'):
            for j in range(self.cols):
                if (self.image_original[i][j] == np.zeros(4)).all():
                    self.image_original[i][j] = np.array([0, 0, 255, 255])
                else:
                    pass
        t2 = time.time()
        cv2.imwrite('./red.png', self.image_original)

    def __temp__(self, i, pbar):
        """并行程序依赖的临时函数

        Args:
            i (int): 图片矩阵的行索引
            pbar (tqdm()): tqdm的进度条实例
        """
        for j in range(self.cols):
            if (self.image_original[i][j] == np.zeros(4)).all():
                self.image_original[i][j] = np.array([0, 0, 255, 255]) # 图片背景修改为红色 | 注意OPENCV的通道是BGR
            else:
                pass
        pbar.update()

    def parallel(self):
        """并行程序
        """
        t1 = time.time()
        with tqdm(total=self.rows, desc='Parallel-Time') as pbar:
            with cf.ThreadPoolExecutor() as tp:
                for i in range(self.rows):
                    tp.submit(self.__temp__, i, pbar)
        t2 = time.time()
        cv2.imwrite('./red.png', self.image_original)


if __name__ == '__main__':
    ChangeBackgroundColor('./original.png')

测试样例

样例输入

样例输出

问题描述

代码命名已经做了多线程并行优化,但速度不但没有提升,反而下降了??

串行在我自己电脑上测试的是8s,并行测试的是23s。

解决方案

会不会是 Python 全局解释锁(GIL)的问题?

(待解决……)

你可能感兴趣的:(python,python,多线程,并行)