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+PIL+Tesseract自动识别验证码进行一键登录
Sep 20 Python
Python+matplotlib实现填充螺旋实例
Jan 15 Python
Python打包方法Pyinstaller的使用
Oct 09 Python
在Python中获取两数相除的商和余数方法
Nov 10 Python
Python逐行读取文件中内容的简单方法
Feb 26 Python
PyQt5 QTableView设置某一列不可编辑的方法
Jun 25 Python
Python中的引用和拷贝实例解析
Nov 14 Python
python 浅谈serial与stm32通信的编码问题
Dec 18 Python
Python 简单计算要求形状面积的实例
Jan 18 Python
python3+opencv生成不规则黑白mask实例
Feb 19 Python
jupyter notebook oepncv 显示一张图像的实现
Apr 24 Python
Django如何在不停机的情况下创建索引
Aug 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
生成卡号php代码
2008/04/09 PHP
PHP cron中的批处理
2008/09/16 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
2016/11/16 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
一些主流JS框架中DOMReady事件的实现小结
2011/02/12 Javascript
可简单避免的三个JS发布错误的详细介绍
2013/08/02 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
javaScript中两个等于号和三个等于号之间的区别介绍
2014/06/27 Javascript
require.js的用法详解
2015/10/20 Javascript
js仿百度登录页实现拖动窗口效果
2016/03/11 Javascript
Windows 系统下设置Nodejs NPM全局路径
2016/04/26 NodeJs
vue 2.0组件与v-model详解
2017/03/27 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
webpack打包react项目的实现方法
2018/06/21 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
vue 使用axios 数据请求第三方插件的使用教程详解
2019/07/05 Javascript
Vue3.x源码调试的实现方法
2019/10/13 Javascript
python处理图片之PIL模块简单使用方法
2015/05/11 Python
利用Python脚本实现ping百度和google的方法
2017/01/24 Python
Python编程实现及时获取新邮件的方法示例
2017/08/10 Python
python取代netcat过程分析
2018/02/10 Python
python判断一个集合是否为另一个集合的子集方法
2018/05/04 Python
python操作excel的包(openpyxl、xlsxwriter)
2018/06/11 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
详解python之heapq模块及排序操作
2019/04/04 Python
python提取log文件内容并画出图表
2019/07/08 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
2020/12/10 Python
pyspark对Mysql数据库进行读写的实现
2020/12/30 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
一款纯css3实现的非常实用的鼠标悬停特效演示
2014/11/05 HTML / CSS
PAUL HEWITT手表美国站:德国北部时尚生活配饰品牌,船锚元素
2017/11/18 全球购物
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
面料业务员岗位职责
2013/12/26 职场文书
毕业实习计划书
2015/01/16 职场文书
2015年前台个人工作总结
2015/04/03 职场文书
goland设置颜色和字体的操作
2021/05/05 Golang