Python中单线程、多线程和多进程的效率对比实验实例


Posted in Python onMay 14, 2019

python的多进程性能要明显优于多线程,因为cpython的GIL对性能做了约束。

Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势。而使用多进程(Multiprocess),则可以发挥多核的优势真正地提高效率。

对比实验

资料显示,如果多线程的进程是CPU密集型的,那多线程并不能有多少效率上的提升,相反还可能会因为线程的频繁切换,导致效率下降,推荐使用多进程;如果是IO密集型,多线程进程可以利用IO阻塞等待时的空闲时间执行其他线程,提升效率。所以我们根据实验对比不同场景的效率

操作系统 CPU 内存 硬盘
Windows 10 双核 8GB 机械硬盘

(1)引入所需要的模块

import requests
import time
from threading import Thread
from multiprocessing import Process

(2)定义CPU密集的计算函数

def count(x, y):
  # 使程序完成150万计算
  c = 0
  while c < 500000:
    c += 1
    x += x
    y += y

(3)定义IO密集的文件读写函数

def write():
  f = open("test.txt", "w")
  for x in range(5000000):
    f.write("testwrite\n")
  f.close()
 
def read():
  f = open("test.txt", "r")
  lines = f.readlines()
  f.close()

(4) 定义网络请求函数

_head = {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}
url = "http://www.tieba.com"
def http_request():
  try:
    webPage = requests.get(url, headers=_head)
    html = webPage.text
    return {"context": html}
  except Exception as e:
    return {"error": e}

(5)测试线性执行IO密集操作、CPU密集操作所需时间、网络请求密集型操作所需时间

# CPU密集操作
t = time.time()
for x in range(10):
  count(1, 1)
print("Line cpu", time.time() - t)
 
# IO密集操作
t = time.time()
for x in range(10):
  write()
  read()
print("Line IO", time.time() - t)
 
# 网络请求密集型操作
t = time.time()
for x in range(10):
  http_request()
print("Line Http Request", time.time() - t)

输出

CPU密集:95.6059999466、91.57099986076355 92.52800011634827、 99.96799993515015
IO密集:24.25、21.76699995994568、21.769999980926514、22.060999870300293
网络请求密集型: 4.519999980926514、8.563999891281128、4.371000051498413、4.522000074386597、14.671000003814697

 (6)测试多线程并发执行CPU密集操作所需时间

counts = []
t = time.time()
for x in range(10):
  thread = Thread(target=count, args=(1,1))
  counts.append(thread)
  thread.start()
 
e = counts.__len__()
while True:
  for th in counts:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print(time.time() - t)

Output: 99.9240000248 、101.26400017738342、102.32200002670288

 (7)测试多线程并发执行IO密集操作所需时间

def io():
  write()
  read()
 
t = time.time()
ios = []
t = time.time()
for x in range(10):
  thread = Thread(target=count, args=(1,1))
  ios.append(thread)
  thread.start()
 
e = ios.__len__()
while True:
  for th in ios:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print(time.time() - t)

Output: 25.69700002670288、24.02400016784668

 (8)测试多线程并发执行网络密集操作所需时间

t = time.time()
ios = []
t = time.time()
for x in range(10):
  thread = Thread(target=http_request)
  ios.append(thread)
  thread.start()
 
e = ios.__len__()
while True:
  for th in ios:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print("Thread Http Request", time.time() - t)

Output: 0.7419998645782471、0.3839998245239258、0.3900001049041748

(9)测试多进程并发执行CPU密集操作所需时间

counts = []
t = time.time()
for x in range(10):
  process = Process(target=count, args=(1,1))
  counts.append(process)
  process.start()
e = counts.__len__()
while True:
  for th in counts:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print("Multiprocess cpu", time.time() - t)

Output: 54.342000007629395、53.437999963760376

 (10)测试多进程并发执行IO密集型操作

t = time.time()
ios = []
t = time.time()
for x in range(10):
  process = Process(target=io)
  ios.append(process)
  process.start()
 
e = ios.__len__()
while True:
  for th in ios:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print("Multiprocess IO", time.time() - t)

Output: 12.509000062942505、13.059000015258789

 (11)测试多进程并发执行Http请求密集型操作

t = time.time()
httprs = []
t = time.time()
for x in range(10):
  process = Process(target=http_request)
  ios.append(process)
  process.start()
 
e = httprs.__len__()
while True:
  for th in httprs:
    if not th.is_alive():
      e -= 1
  if e <= 0:
    break
print("Multiprocess Http Request", time.time() - t)

Output: 0.5329999923706055、0.4760000705718994

 实验结果

CPU密集型操作 IO密集型操作 网络请求密集型操作
线性操作 94.91824996469 22.46199995279 7.3296000004
多线程操作 101.1700000762 24.8605000973 0.5053332647
多进程操作 53.8899999857 12.7840000391 0.5045000315

通过上面的结果,我们可以看到:

多线程在IO密集型的操作下似乎也没有很大的优势(也许IO操作的任务再繁重一些就能体现出优势),在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了

多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行

以上所述是小编给大家介绍的Python单线程多线程和多进程效率对比详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python Queue模块详解
Nov 30 Python
Python使用Flask框架同时上传多个文件的方法
Mar 21 Python
Python导出DBF文件到Excel的方法
Jul 25 Python
Python 将pdf转成图片的方法
Apr 23 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
关于阿里云oss获取sts凭证 app直传 python的实例
Aug 20 Python
python线程安全及多进程多线程实现方法详解
Sep 27 Python
Django框架表单操作实例分析
Nov 04 Python
基于Pycharm加载多个项目过程图解
Jan 19 Python
TensorFlow2.0:张量的合并与分割实例
Jan 19 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
Jun 08 Python
推荐技术人员一款Python开源库(造数据神器)
Jul 08 Python
Dlib+OpenCV深度学习人脸识别的方法示例
May 14 #Python
Python发展简史 Python来历
May 14 #Python
Python基础知识点 初识Python.md
May 14 #Python
Python应用领域和就业形势分析总结
May 14 #Python
python文件写入write()的操作
May 14 #Python
python时间序列按频率生成日期的方法
May 14 #Python
python的依赖管理的实现
May 14 #Python
You might like
关于手调机和数调机的选择
2021/03/02 无线电
php生成随机数或者字符串的代码
2008/09/05 PHP
探讨Smarty中如何获取数组的长度以及smarty调用php函数的详解
2013/06/20 PHP
PHP数据库操作之基于Mysqli的数据库操作类库
2014/04/19 PHP
PHP魔术引号所带来的安全问题分析
2014/07/15 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
2017/05/02 PHP
PHP图片水印类的封装
2017/07/06 PHP
PHP设计模式之工厂模式实例总结
2017/09/01 PHP
基于php双引号中访问数组元素报错的解决方法
2018/02/01 PHP
node.js中的events.emitter.removeListener方法使用说明
2014/12/10 Javascript
jQuery中:file选择器用法实例
2015/01/04 Javascript
javascirpt实现2个iframe之间传值的方法
2016/06/30 Javascript
浅谈jQuery中的checkbox问题
2016/08/10 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
详谈js的变量提升以及使用方法
2018/10/06 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
微信小程序实现3D轮播图效果(非swiper组件)
2019/09/21 Javascript
微信小程序如何获取地址
2019/12/24 Javascript
[59:32]Liquid vs Fnatic 2019国际邀请赛淘汰赛败者组BO1 8.20.mp4
2020/07/19 DOTA
python通过zlib实现压缩与解压字符串的方法
2014/11/19 Python
python杀死一个线程的方法
2015/09/06 Python
python实现简单颜色识别程序
2020/02/19 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
Python 求向量的余弦值操作
2021/03/04 Python
玩具反斗城西班牙网上商城:ToysRUs西班牙
2017/01/19 全球购物
纽约手袋品牌:KARA
2018/03/18 全球购物
毕业生个人的求职信范文
2013/12/03 职场文书
工业学校毕业生自荐信范文
2014/01/03 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
父母寄语大全
2014/04/12 职场文书
主题党日活动总结
2014/07/08 职场文书
优秀共产党员演讲稿
2014/09/04 职场文书
小学秋季运动会通讯稿
2015/11/25 职场文书
JavaScript实现登录窗体
2021/06/22 Javascript