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中使用 Selenium 实现网页截图实例
Jul 18 Python
python批量同步web服务器代码核心程序
Sep 01 Python
python快速查找算法应用实例
Sep 26 Python
Python单体模式的几种常见实现方法详解
Jul 28 Python
python实现随机漫步方法和原理
Jun 10 Python
python+openCV利用摄像头实现人员活动检测
Jun 22 Python
如何解决tensorflow恢复模型的特定值时出错
Feb 06 Python
python opencv 检测移动物体并截图保存实例
Mar 10 Python
浅析python 动态库m.so.1.0错误问题
May 09 Python
Python使用jpype模块调用jar包过程解析
Jul 29 Python
python 实现控制鼠标键盘
Nov 27 Python
Pytorch DataLoader shuffle验证方式
Jun 02 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
德生1994机评
2021/03/02 无线电
PHP中for循环语句的几种变型
2006/11/26 PHP
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
破解图片防盗链的代码(asp/php)测试通过
2010/07/02 PHP
Laravel 创建指定表 migrate的例子
2019/10/09 PHP
jQuery文件上传插件Uploadify使用指南
2014/06/05 Javascript
js的touch事件的实际引用
2014/10/13 Javascript
jQuery中attr()方法用法实例
2015/01/05 Javascript
jQuery实现彩带延伸效果的网页加载条loading动画
2015/10/29 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
javascript实现瀑布流动态加载图片原理
2016/08/12 Javascript
js中json处理总结之JSON.parse
2016/10/14 Javascript
微信小程序 网络API 上传、下载详解
2016/11/09 Javascript
JavaScript无缝滚动效果的实例代码
2017/03/27 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
vue.js $refs和$emit 父子组件交互的方法
2017/12/20 Javascript
vue 实现滚动到底部翻页效果(pc端)
2019/07/31 Javascript
利用JS代码自动删除稿件的普通弹幕功能
2019/09/20 Javascript
python实现html转ubb代码(html2ubb)
2014/07/03 Python
Python 功能和特点(新手必学)
2015/12/30 Python
使用Python的package机制如何简化utils包设计详解
2017/12/11 Python
python3解析库lxml的安装与基本使用
2018/06/27 Python
Python3.7 dataclass使用指南小结
2019/02/22 Python
wxPython实现整点报时
2019/11/18 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
2020/02/28 Python
Python callable内置函数原理解析
2020/03/05 Python
收集的7个CSS3代码生成工具
2010/04/17 HTML / CSS
html5 自定义播放器核心代码
2013/12/20 HTML / CSS
HTML5 客户端数据库简易使用:IndexedDB
2019/12/19 HTML / CSS
英国领先的NHS批准的在线药店:Pharmacy2U
2017/01/06 全球购物
京东奢侈品:全球奢侈品牌
2018/03/17 全球购物
美国家居装饰购物网站:Amanda Lindroth
2020/03/25 全球购物
应届大专生求职信
2014/06/26 职场文书
出国留学导师推荐信
2015/03/26 职场文书
ConstraintValidator类如何实现自定义注解校验前端传参
2021/06/18 Java/Android
Python 避免字典和元组的多重嵌套问题
2022/07/15 Python