使用进程池/线程池 加速 Python数据处理

使用进程池/线程池 加速 Python数据处理

  • 目标
    • 简单模式
    • 多进程模式
  • 参考

Python 是一种出色的编程语言,可用于处理数据和自动执行重复任务。尽管 Python 使编码变得有趣,但它并不总是运行速度最快的。默认情况下,Python 程序使用单个 CPU 作为单个进程执行。

如果有一台近十年生产的计算机,它很可能有 4 个(或更多)CPU 核心。这意味着在等待程序完成运行时,计算机 75% 或更多的资源几乎处于闲置状态! 如何通过并行运行 Python 函数来充分利用计算机的处理能力。得益于Python的concurrent.futures模块,只需要3行代码就可以将一个普通程序变成可以并行处理数据的程序。

目标

假设有一个装满照片的文件夹,想要创建每张照片的缩略图。 这是一个简短的程序,它使用 Python 的内置 glob 函数获取文件夹中所有 jpeg 文件的列表,然后使用 Pillow 图像处理库保存每张照片的 128 像素缩略图;

简单模式

# thumbnails_1.py
import glob
import os
from PIL import Imagedef make_image_thumbnail(filename):# 缩略图将被命名为"<original_filename>_thumbnail.jpg"base_filename, file_extension = os.path.splitext(filename)thumbnail_filename = f"{base_filename}_thumbnail{file_extension}"# 创建和存储缩略图image = Image.open(filename)image.thumbnail(size=(128, 128))image.save(thumbnail_filename, "JPEG")return thumbnail_filename# 遍历文件夹下的所有jpg文件并为每一张图生成缩略图
for image_file in glob.glob("*.jpg"):thumbnail_file = make_image_thumbnail(image_file)print(f"A thumbnail for {image_file} was saved as {thumbnail_file}")

该程序运行时间为 8.9 秒。但是计算机大概有75%的cpu处于空闲状态;问题是电脑有 4 个 CPU 核心,但 Python 只使用其中之一。因此当最大限度地发挥一个 CPU时,其他三个 CPU 却没有执行任何操作。

多进程模式

将 jpeg 文件列表分成 4 个较小的块。 运行 4 个独立的 Python 解释器实例。让每个 Python 实例处理 4 个数据块之一。 合并 4 个过程的结果即可得到最终结果列表。 在四个独立的 CPU 上运行的四个 Python 副本应该能够完成大约是一个 CPU 的 4 倍的工作量,对吗?
只需要3步:

  1. 导入concurrent.futures库;

  2. 启动 4个Python 实例通过创建一个进程池来做到这一点;

  3. 要求进程池使用这 4 个进程在数据列表上执行辅助函数。executor.map() 函数接受要调用的辅助函数以及要使用它处理的数据列表。它完成了拆分列表、将子列表发送到每个子进程、运行子进程以及组合结果等所有艰苦工作。非常的简洁!

    executor.map() 函数返回结果的顺序与给它处理的数据列表的顺序相同。所以使用Python的zip()函数作为快捷方式来一步获取原始文件名和匹配结果。

# thumbnails_2.pyimport glob
import os
from PIL import Image
import concurrent.futuresdef make_image_thumbnail(filename):# 缩略图将被命名为"<original_filename>_thumbnail.jpg"base_filename, file_extension = os.path.splitext(filename)thumbnail_filename = f"{base_filename}_thumbnail{file_extension}"# 创建和存储缩略图image = Image.open(filename)image.thumbnail(size=(128, 128))image.save(thumbnail_filename, "JPEG")return thumbnail_filename# 创建一个线程池处理,为每个cpu创建一个实例
with concurrent.futures.ProcessPoolExecutor() as executor:# 获取所有要处理的jpg文件image_files = glob.glob("*.jpg")# 处理文件列表 将任务拆分到线程池以利用所有的cpufor image_file, thumbnail_file in zip(image_files, executor.map(make_image_thumbnail, image_files)):print(f"A thumbnail for {image_file} was saved as {thumbnail_file}")

2.2秒就完成了!与原始版本相比,速度提高了 4 倍。由于使用 4 个 CPU 而不是 1 个,因此运行时间更快。 但如果仔细观察,你会发现“用户”时间几乎是 9 秒。程序如何在 2.2 秒内完成但仍然运行了 9 秒?这似乎……不可能? 这是因为“用户”时间是所有 CPU 的 CPU 时间的总和。

生成更多 Python 进程并在它们之间调整数据会产生一些开销,因此并不总是能获得如此大的速度提升。 如果正在处理巨大的数据集,那么设置 chunksize 参数的技巧可以提供很大帮助。 当有要处理的数据列表并且每条数据都可以独立处理时,使用进程池是一个很好的解决方案。

以下是适合多处理的一些示例:

  • 从一组单独的 Web 服务器日志文件中获取统计信息
  • 从一堆 XML、CSV 或 json 文件中解析数据
  • 预处理大量图像以创建机器学习数据集

但进程池并不总是答案。使用进程池需要在单独的 Python 进程之间来回传递数据。如果正在使用的数据无法在进程之间有效传递,那么这将不起作用。 如果你需要处理上一条数据的结果来处理下一条数据,这也是行不通的。 这种情况下适合用Python 有一个全局解释器锁(Global Interpreter Lock),即 GIL。这意味着即使程序是多线程的,任何线程一次也只能执行一条 Python 代码指令。换句话说,多线程Python代码无法真正并行运行。 但进程池可以解决这个问题! 因为运行的是真正独立的 Python 实例,所以每个实例都有自己的 GIL。

可以获得 Python 代码的真正并行执行(以一些额外开销为代价)。 不要害怕并行处理! 借助concurrent.futures 库,Python提供了一种简单的方法来调整脚本以同时使用计算机中的所有 CPU 核心。

参考

  • https://medium.com/@ageitgey/quick-tip-speed-up-your-python-data-processing-scripts-with-process-pools-cf275350163a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/193990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2022年9月8日 Go生态洞察:Go Developer Survey 2022 Q2 结果分析

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

物奇平台电容触摸功能调试

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 物奇平台电容触摸功能调试 1 修改按键驱动宏 2 编译生成wpk 文件,import 导入烧录文件。…

水果编曲软件fl studio手机版下载

fl studio mobile手机版中文名水果编曲软件&#xff0c;它是一款非常不错的音乐编曲软件&#xff0c;凭借简单易上手的操作方式&#xff0c;强悍且实用的功能&#xff0c;深受到了音乐创作者的喜爱&#xff0c;不仅仅提供了广阔的音乐创作空间&#xff0c;可以让用户对舞曲、轻…

工具网站:随机生成图片的网站

一个随机生成图片的网站&#xff1a;Lorem Picsum。 有时候&#xff0c;我们做静态页面需要大量图片去填充内容&#xff0c;以使用该网站去生成指定尺寸的图片。每次打开页面都会获取不同的图片&#xff0c;就不用我们做静态页面开发的时候&#xff0c;绞尽脑汁去找图片了。 …

原型设计模式

4. 原型设计模式 4.1 浅拷贝 在Java编程中&#xff0c;浅拷贝是指在复制对象时&#xff0c;只复制对象的基本数据类型的值和引用类型的地址&#xff0c;不复制引用类型指向的对象本身。浅拷贝可以用于一些简单的场景&#xff0c;例如对象的基本属性不包含其他对象的引用类型&…

振南技术干货集:ChatGPT,现在我做单片机/嵌入式开发已经离不开它了!(2)

注解目录 &#xff08;此文部分内客由 ChatGPT 生成&#xff0c;你分得出来哪些是人写的&#xff0c;哪些是 ChatGPT 生成的吗?&#xff09; 20.1 恐怖的 ChatGPT 2023年ChatGPT有多火?比 TikTok火4 倍都不止!什么是“范式革命”?从石器时代到飞机大炮就是范式革命。AI绘…

C语言速通笔记(1-40)

1&#xff0e;一个 C 语言程序有且只有一个 main 函数&#xff0c;是程序运行的起点。 2&#xff0e;每个 C 语言程序写完后&#xff0c;都是先编译&#xff0e; c 后链接&#xff0e; obj 最后运行&#xff0e;. exe 3.c和&#xff0e; obj 文件是无法运行的&#xff0c;只有…

Python读取栅格遥感影像并加以辐射校正后导出为Excel的一列数据

本文介绍基于Python语言中的gdal模块&#xff0c;读取一景.tif格式的栅格遥感影像文件&#xff0c;提取其中每一个像元的像素数值&#xff0c;对像素值加以计算&#xff08;辐射定标&#xff09;后&#xff0c;再以一列数据的形式将计算后的各像元像素数据保存在一个.csv格式文…

Redis基础知识

目录 一、为什么要用到Redis? 二、Redis 为什么运行比较快&#xff1f; 三、Redis的数据结构 四、Redis可以实现什么功能&#xff1f; 五、Redis 保证数据持久化方式 1、持久化方式主要有2种&#xff1a;RDB 和 AOF 2、RDB和AOF区别&#xff1f; 六、Redis 中的过期删…

IDA常用操作、快捷键总结以及使用技巧

先贴一张官方的图&#xff0c;然后我再总结一下&#xff0c;用的频率比较高的会做一些简单标注 快捷键 F系列【主要是调试状态的处理】 F2 添加/删除断点F4 运行到光标所在位置F5 反汇编F7 单步步入F8 单步跳过F9 持续运行直到输入/断点/结束 shift系列【主要是调出对应的页…

洛谷 P9389 烂柯杯 C++代码

目录 前言 思路点拨 AC代码 结尾 前言 今天我们来做洛谷上的一道题目。 网址&#xff1a;[THUPC 2023 决赛] 烂柯杯 - 洛谷 题目&#xff1a; 乱七八糟一堆文字&#xff0c;展示不下。 思路点拨 思路1&#xff1a;和围棋有关的人&#xff0c;很容易想到柯洁。 思路2&…

【RotorS仿真系列】Ardrone模型介绍

ardrone是rotors仿真框架提供的一款机型&#xff0c;因为该机型与我们实际使用的机型参数相近&#xff0c;所以这里对它的参数做特别整理和记录。 一、模型参数总结 ardrone的gazebo模型如下图所示&#xff1a; 根据ardrone.yaml&#xff0c;其关键参数如下所示&#xff1a…

Project 1: The Game of Hog(CS61A)

&#xff08;第一阶段&#xff09;问题 5a&#xff08;3 分&#xff09; 实现该函数&#xff0c;该函数模拟了完整的 Hog 游戏。球员 交替轮流掷骰子&#xff0c;直到其中一名玩家达到分数。playgoal 您现在可以忽略 Feral Hogs 规则和论点; 您将在问题 5b 中实现它。feral_h…

UC++中的头文件和宏的那些事儿

假定有如下继承自AActor类的.h文件&#xff1a; #pragma once#include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "MoveRandom.generated.h"UCLASS() class DEMO01_API AMoveRandom : public AActor {GENERATED_BODY()public…

车联网架构设计(一)_消息平台的搭建

车联网是物联网的一个主要应用方向&#xff0c;车辆通过连接车联网平台&#xff0c;实时进行消息的交互&#xff0c;平台可以提供车辆远程控制&#xff0c;故障检测&#xff0c;车路协同等各方面的功能。 我在车联网行业从事了很长时间的技术工作&#xff0c;参与了整个车联网…

树莓派多串口通信

树莓派多串口通信 串口配置串口通信函数分析串口通信示例代码 参考博文1&#xff1a;树莓派 4 UART 多串口配置通信参考博文2&#xff1a;树莓派wiringPi库详解关于树莓派相关其他环境配置可参考&#xff1a;快速上手树莓派关于wiringPi库初始化与IO口开发可参考&#xff1a;树…

深入探索FastAPI单元测试:使用TestClient轻松测试你的API

原文&#xff1a;深入探索FastAPI单元测试&#xff1a;使用TestClient轻松测试你的API-51CTO.COM 当使用FastAPI进行单元测试时&#xff0c;一个重要的工具是TestClient类。TestClient类允许我们模拟对FastAPI应用程序的HTTP请求&#xff0c;并测试应用程序的响应。这使我们能…

调优--学习笔记

1&#xff0c;Presto调优 数据存储格式 1&#xff09;合理设置分区 与Hive类似&#xff0c;Presto会根据元信息读取分区数据&#xff0c;合理的分区能减少Presto数据读取量&#xff0c;提升查询性能。 2&#xff09;使用列式存储 Presto对ORC文件读取做了特定优化&#xff0c…

Qt OpenCV 学习(一):环境搭建

对应版本 Qt 5.15.2OpenCV 3.4.9MinGW 8.1.0 32-bit 1. OpenCV 下载 确保安装 Qt 时勾选了 MinGW 编译器 本文使用 MinGW 编译好的 OpenCV 库&#xff0c;无需自行编译 确保下载的 MinGW 和上述安装 Qt 时勾选的 MinGW 编译器位数一致&#xff0c;此处均为 x86/32-bit下载地址…

《微信小程序开发从入门到实战》学习四十

4.2 云开发JSON数据库 4.2.11 更新数据 使用数据库API更新数据有两种方法&#xff1a;一.将记录局部更新的update方法&#xff1b;二.以替换的方式更新记录的set方法 update方法可以局部更新一个记录或一个集合的多个记录&#xff0c;更新时只有指定字段更新&#xff0c;其他…