python多线程和异步性能对比_python对比线程,进程,携程,异步,哪个快

目录

概念介绍

测试环境

开始测试

测试【单进程单线程】

测试【多进程 并行】

测试【多线程 并发】

测试【协程 + 异步】

结果对比

绘图展示

概念介绍

首先简单介绍几个概念:

进程和线程

进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资源)。

线程也叫轻量级进程,它是一个基本的 CPU 执行单元,是比进程更小的能独立运行的基本单位。

进程和线程的关系:

一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

资源分配给进程,同一进程的所有线程共享该进程的所有资源。

CPU 分给线程,即真正在 CPU 上运行的是线程。

并行和并发

并行处理是计算机系统中能同时执行两个或更多个处理的一种计算方法。并行处理可同时工作于同一程序的不同方面,其主要目的是节省大型和复杂问题的解决时间。

并发处理指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个 CPU 上运行,但任一个时刻点上只有一个程序在 CPU 上运行。

并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集。多进程是并行的,多线程是并发的。

同步和异步

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

举个例子,打电话时就是同步通信,发短息时就是异步通信。

测试环境

进行对比测试之前,我们先来创建一个合适的实验环境:

模拟一个需要等待一定时间才可以获取返回结果的网页。

如果直接用百度、CSDN 等站点的话,一方面响应太快、难以看出各种方法的差距,另一方面响应速度会受网速影响、每次发送请求获取响应所需的时间不完全一致导致重复实验结果差距较大,所以在此用 Flask 模拟一个本地慢速服务器。

flask_server.py 代码如下:

from flask import Flask # pip install flask

import time

app = Flask(__name__)

@app.route('/')

def index():

time.sleep(3) # 休眠 3 秒再返回结果

return 'Hello!'

if __name__ == '__main__':

app.run(threaded=True) # 以多线程模式启动服务

启动之后,Flask 服务默认在 127.0.0.1:5000 上运行,控制台输出结果如下:

* Serving Flask app "flask_server" (lazy loading)

* Environment: production

WARNING: Do not use the development server in a production environment.

Use a production WSGI server instead.

* Debug mode: off

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

在浏览器中访问 http://127.0.0.1:5000/ 等待 3 秒即会出现 Hello! 页面,表明简单的慢速服务器搭建完成!

开始测试

首先导入需要的模块,以请求 10 次为例准备 urls,再定义一个 get_html_text() 函数:

import requests

import time

# 用于多进程

from multiprocessing import Process

# 用于多线程

from threading import Thread

# 用于协程+异步

import asyncio

import aiohttp # pip install aiohttp

urls = ['http://127.0.0.1:5000' for _ in range(10)]

def get_html_text(url):

response = requests.get(url)

return response.text

测试【单进程单线程】

start = time.time()

for url in urls:

result = get_html_text(url)

print(result)

end = time.time()

print('【单进程单线程】耗时:%s 秒' %(end - start))

结果如下:

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

【单进程单线程】耗时:30.15605854988098 秒

测试【多进程 并行】

start = time.time()

processes = []

for url in urls:

p = Process(target=get_html_text, args=(url,))

processes.append(p)

p.start()

for p in processes:

p.join()

print('Hello!')

end = time.time()

print('【多进程 并行】耗时:%s 秒' %(end - start))

结果如下(测试电脑为 4 核 CPU,核心数越大加速越明显):

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

【多进程 并行】耗时:5.511234283447266 秒

测试【多线程 并发】

start = time.time()

threads = []

for url in urls:

t = Thread(target=get_html_text, args=(url,))

threads.append(t)

t.start()

for t in threads:

t.join()

print('Hello!')

end = time.time()

print('【多线程 并发】耗时:%s 秒' %(end - start))

结果如下:

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

【多线程 并发】耗时:3.030653953552246 秒

测试【协程 + 异步】

# 因为 requests 模块不支持异步操作,需要借助 aiohttp 模块

async def get_html_text_async(url):

async with aiohttp.ClientSession() as session:

async with session.get(url) as response:

text = await response.text()

return text

start = time.time()

tasks = [asyncio.ensure_future(get_html_text_async(url)) for url in urls]

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))

for task in tasks:

print(task.result())

end = time.time()

print('【协程 ++ 异步】耗时:%s 秒' %(end - start))

结果如下:

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

Hello!

【协程 ++ 异步】耗时:3.046288251876831 秒

结果对比

len(urls)==1:

单进程单线程3。0078秒

多进程 并发 3.83秒

多线程并发3.0073秒

携程+异步3.0133

len(urls)==4:

单进程单线程12秒

多进程 并发 4秒

多线程并发3.01秒

携程+异步3.02秒

len(urls)==10:

单进程单线程30.1秒

多进程 并发 5.5秒

多线程并发3.030秒

携程+异步3.046秒

len(urls)==100:

单进程单线程301.10秒

多进程 并发 23.81秒

多线程并发3.15秒

携程+异步3.19秒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-ui介绍uni-api

一、uni-ui介绍 安装 二、uni-api 解决uni-app中的跨域问题: "h5" : {"router" : {"mode" : "hash"},"devServer": {"https": false,"proxy": {"/web": {"target": …

推算生日的故事

小明和小强都是张老师的学生,张老师的生日是某月某日,2人都不知道张老师的生日。 生日是下列10组中一天: 3月4日 3月5日 3月8日 6月4日 6月7日 9月1日 9月5日 12月1日 12月2日 12月8日 张老师把月份告诉了小明,把日子告诉了小强…

ubuntu18.04安装python3_在 Ubuntu 18.04 上安装 Python 3.7

扩展源安装sudo apt updatesudo apt install software-properties-commonsudo add-apt-repository ppa:deadsnakes/ppa# 按回车继续sudo apt install python3.7python3.7 --version#安装pipwget https://bootstrap.pypa.io/get-pip.pypython3.7 get-pip.py#安装python3.7-devel…

一、uniapp项目(封装异步请求、moment.js时间处理、封装手势滑动组件、下载图片到本地)

一、封装异步请求: 1. 为什么要封装? 2. 封装的思路 export default (params) > {// 显示加载中uni.showLoading({title: "加载中"})return new Promise((resolve, reject) > {wx.request({...params,success(res) {resolve(res)},fail…

.net中如何发送HTTP请求网络资源

应用场景 应该说只要是需要通过发送Http请求获取网络资源的地方都要使用它,网络资源可以是指以URI来表示的资源,比如web api接口等。 HttpWebRequest .net2.0 ~ .net4.0使用HttpWebRequest 代码如下: 1 //.net2.0 ~ .net4.0使用HttpWebReque…

python ftplib_python:使用ftplib编写FTP客户端

Python中的ftplib模块Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件FTP的工作流程及基本操作可参考协议RFC959ftp登陆连接from ftplib import FTP #加载ftp模块ftpFTP() #设置变量ftp…

二、uniapp项目(分段器的使用、scroll-view、视频下载、转发)

一、分段器组件的使用 uniapp官方文档 <template><view class"category"><view class"category_tab"> <view class"category_tab_title"><view class"title_inner"><uni-segmented-control :curr…

HTTP 请求头中的 X-Forwarded-For

本文转载自https://imququ.com/post/x-forwarded-for-header-in-http.html 我一直认为&#xff0c;对于从事 Web 前端开发的同学来说&#xff0c;HTTP 协议以及其他常见的网络知识属于必备项。一方面&#xff0c;前端很多工作如 Web 性能优化&#xff0c;大部分规则都跟 HTTP、…

【Bash/Shell】知识总结

文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…

problem b: 一年中的第几天_第九届蓝桥杯B组试题

1.标题&#xff1a;第几天2000年的1月1日&#xff0c;是那一年的第1天。那么&#xff0c;2000年的5月4日&#xff0c;是那一年的第几天&#xff1f;注意&#xff1a;需要提交的是一个整数&#xff0c;不要填写任何多余内容。“手动分割”大小月判断&#xff1a;https://jingyan…

一、express 路由 todos案例

一、express路由 动态路由参数 params 路径参数 query 二、 todos案例 2.1 准备工作 新建一个文件夹01-demo执行npm init -y 生成package.json配置文件执行npm install express --save 安装express新建app.js文件&#xff0c;这是程序的入口文件新建db.json文件&#xff0…

Spiral Matrix I II

Spiral Matrix I Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order. Example Given n 3, You should return the following matrix: [[ 1, 2, 3 ],[ 8, 9, 4 ],[ 7, 6, 5 ] ]分析&#xff1a;从上&#xff0c;右&#xff0c…

二、express中间件

一、中间件引入 实现加入日志模块功能&#xff1a; 1. 我们能想到的方案&#xff1a; 将日志输出代码封装到函数中&#xff0c;然后需要日志输出的地方调用这个函数即可。 app.js文件&#xff1a; const express require(express)const app express()const myLogger (r…

移动端中如何检测设备方向的变化?

除非你的应用程序限定了只在移动设备直立状态或水平状态下使用&#xff0c;一般情况下&#xff0c;你需要调整一些设定。即便你设计的布局流畅时尚&#xff0c;你可能需要改变某些编程代码。通常有以下一些小的策略用于检测移动设备方向的改变。 orientationchange事件 你等待一…

python函数名与变量名可以一样吗_python--第一类对象,函数名,变量名

一 . 第一类对象函数对象可以像变量一样进行赋值 , 还可以作为列表的元素进行使用可以作为返回值返回 , 可以作为参数进行传递def func():def people():print(金_卡戴珊)print(oh,yes!)print(oh,baby!)return peopleret func()ret()二 . 闭包闭包 -> 函数的嵌套内层函数对外…

Mac Pro 修改环境变量

参考&#xff1a;Ubuntu 12 修改环境变量 【实战】 把 php、php-fpm、nginx、mysql 的相关命令路径添加到 用户环境变量 $ vim ~/.bash_profile alias llls -alF alias lals -A alias lls -CFexport GOROOT/usr/local/go export GOPATH/Users/jianbao/GoProjects/go-studyexpor…

三、Express 路由

一、路由 路由是指应用程序的端点(URI)如何响应客户端请求. 你可以使用app与HTTP方法相对应的Express对象的方法来定义路由. 例如,app.get()处理GET请求和app.post POST 请求。 你还可以使用app.all()处理所有HTTP方法,并使用app.use()将中间件指定为回调函数. 这些路由方法…

python程序操作的核心_python核心编程-第五章-个人笔记

1.用del删除对对象的引用>>> a 123>>>a123>>> dela>>>aTraceback (most recent call last):File"", line 1, in NameError : namea is not defined2.整型(1)布尔型 该类型取值范围只要两个值&#xff1a;布尔值True 和 布尔…

辅助同步器

java除了提供锁之外&#xff0c;还提供了一些辅助的同步器。 一、CountDownLatch 作用&#xff1a;常常要有一个线程&#xff08;master&#xff09;做汇总&#xff0c;等n个子步骤&#xff08;线程slave&#xff09;完成后才能继续操作。用join写只能等子线程完成&#xff0c;…

RESTful 接口设计规范

一、RESTful 接口设计规范 1. 协议 API与用户的通信协议&#xff0c;尽量使用HTTPs协议。 2. 域名 应该尽量将API部署在专用域名之下。 https://api.example.com 如果确定API很简单&#xff0c;不会有进一步扩展&#xff0c;可以考虑放在主域名下。 https://example.org/ap…