本文将使用场景化为案例,将单线程,多线程,多进程,异步协程的速度进行对比
对比速度时, >表示 速度快于 >>表示速度远快于 =表示速度差不多 >>>>表示速度远远快于
电脑硬软件配置:
CPU 6600HS, 6核12线程
GPU 16G,打开电脑后,可用内存不到7G
python版本 3.8.5
--------------------------
案例一:
定义函数fnc,,计算一亿次,循环该函数5次,也就是共计算5亿次
CPU表示我不是人,但你做的不是人事.
多进程完胜
速度: 进程池>多进程>>多线程>单线程>异步协程
需要注意的是:
fnc函数中,用列表推导式 和 只用for循环:
时间差和占用的内存都体现在:创建了5个列表,该列表有1亿个元素
所以,如果在非常庞大的运行程序中,必须要格外注意程序运行占用的空间
池的存在是优于不建池的存在的,原因是池减少了线程反复创建的开销
协程异步消耗的资源比多线程,多进程要少很多
计算型任务常规的多进程完胜,而建立进程池又完胜常规的多进程
以下案例中,将不再展示多线程,多进程,统一替换成线程池,进程池
--------------------------
案例二:
定义函数fnc,,每次程序停止运行2秒,模拟函数运行消耗的时间,无关IO密集或者计算密集
异步完胜
异步>>线程池=进程池>>单线程
--------------------------
案例三:
定义函数fnc,计算一千万次,循环该函数50次
多线程,多进程完胜,异步拉跨
速度: 线程池>>进程池>>>>单线程>异步协程
--------------------------
案例四:
定义函数fnc,做一次计算,小循环该函数5万次,大循环5次
单线程完胜
速度: 单线程>>>> >>>>异步协程>线程池>>>> >>>>进程池
--------------------------
>>>线程一般会经历新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)5 种状态,当线程被创建并启动后,并不会直接进入运行状态,也不会一直处于运行状态,CPU 可能会在多个线程之间切换,线程的状态也会在就绪和运行之间转换。
>>>计算密集型任务,特点是进行大量的计算,消耗CPU资源.比如:计算圆周率,对视频进行解码....
>>>I/O密集型任务: I代表input输入,O代表inout,他们的特点是CPU消耗很少,因为CPU和内存的速度远远大于 I/O操作的速度,所以任务的大部分时间都在等待IO操作完成,
故以上四个案例可以视为:
案例一代表纯CPU计算------进程池完胜
案例二代表CPU耗时=IO耗时------协程异步完胜
案例三代表少量CPU计算, 大量IO操作(相对于CPU计算的时间是大量的)------线程池完胜
案例四代表极少量CPU计算------单线程完胜
--------------------------
进程程池进程数量设置: CPU核数 + 1
线程池线程数量设置: CPU核数 * [ 1 + (IO耗时 / CPU耗时) ]
异步协程: 本质是程序里面的函数,线程的上下文(CPU计算和IO操作)切换由我们自己控制,通常资源消耗最少,所以有微线程之称.