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秒
總結
以上是生活随笔為你收集整理的python多线程和异步性能对比_python对比线程,进程,携程,异步,哪个快的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Inception(Pytorch实现)
- 下一篇: SyntaxError: Non-ASC