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实现截图图片并保存截取的图片
Jan 05 Python
Python中Proxypool库的安装与配置
Oct 19 Python
Python数据抓取爬虫代理防封IP方法
Dec 23 Python
Python列表(List)知识点总结
Feb 18 Python
Django连接数据库并实现读写分离过程解析
Nov 13 Python
Python短信轰炸的代码
Mar 25 Python
pip安装提示Twisted错误问题(Python3.6.4安装Twisted错误)
May 09 Python
python根据字典的键来删除元素的方法
Aug 16 Python
python爬取某网站原图作为壁纸
Jun 02 Python
能让Python提速超40倍的神器Cython详解
Jun 24 Python
pytorch分类模型绘制混淆矩阵以及可视化详解
Apr 07 Python
用Python仅20行代码编写一个简单的端口扫描器
Apr 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
受疫情影响 动画《Re从零开始的异世界生活》第二季延期至7月
2020/03/10 日漫
php 转换字符串编码 iconv与mb_convert_encoding的区别说明
2011/11/10 PHP
php curl 伪造IP来源的实例代码
2012/11/01 PHP
下拉列表多级联动dropDownList示例代码
2013/06/27 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
用javascript实现分割提取页面所需内容
2007/05/09 Javascript
ExtJS4 表格的嵌套 rowExpander应用
2014/05/02 Javascript
有关json_decode乱码及NULL的问题
2015/10/13 Javascript
深入理解JS实现快速排序和去重
2016/10/17 Javascript
jQuery基于ajax操作json数据简单示例
2017/01/05 Javascript
jQuery之动画ajax事件(实例讲解)
2017/07/18 jQuery
微信小程序表单弹窗实例
2018/07/19 Javascript
解决jquery有正确返回值但不执行success函数的问题
2018/08/20 jQuery
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
2019/10/23 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
[01:14:35]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第一局
2016/02/26 DOTA
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
python如何实现反向迭代
2018/03/20 Python
python skimage 连通性区域检测方法
2018/06/21 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
python自动化测试之异常及日志操作实例分析
2019/11/09 Python
pycharm新建Vue项目的方法步骤(图文)
2020/03/04 Python
Xadmin+rules实现多选行权限方式(级联效果)
2020/04/07 Python
基于tensorflow for循环 while循环案例
2020/06/30 Python
一些PHP的面试题
2015/05/06 面试题
中专毕业自我鉴定
2013/10/16 职场文书
竞选学习委员演讲稿
2014/04/28 职场文书
抗洪抢险事迹材料
2014/05/06 职场文书
4s店活动策划方案
2014/08/25 职场文书
2014年质量工作总结
2014/11/22 职场文书
刑事附带民事上诉状
2015/05/23 职场文书
2015年图书馆个人工作总结
2015/05/26 职场文书
Redis字典实现、Hash键冲突及渐进式rehash详解
2021/09/04 Redis
讨论nginx location 顺序问题
2022/05/30 Servers