python 多線程與多進(jìn)程效率測(cè)試
1、概述
在Python中,計(jì)算密集型任務(wù)適用于多進(jìn)程,IO密集型任務(wù)適用于多線程
正常來(lái)講,多線程要比多進(jìn)程效率更高,因?yàn)檫M(jìn)程間的切換需要的資源和開(kāi)銷更大,而線程相對(duì)更小,但是我們使用的Python
大多數(shù)的解釋器是Cpython
,眾所周知Cpython
有個(gè)GIL鎖
,導(dǎo)致執(zhí)行計(jì)算密集型
任務(wù)時(shí)多線程實(shí)際只能是單線程
,而且由于線程之間切換的開(kāi)銷導(dǎo)致多線程往往比實(shí)際的單線程還要慢,所以在 python 中計(jì)算密集型任務(wù)通常使用多進(jìn)程,因?yàn)楦鱾€(gè)進(jìn)程有各自獨(dú)立的GIL,互不干擾。
而在IO密集型
任務(wù)中,CPU時(shí)常處于等待狀態(tài),操作系統(tǒng)需要頻繁與外界環(huán)境進(jìn)行交互,如讀寫(xiě)文件,在網(wǎng)絡(luò)間通信等。在這期間GIL會(huì)被釋放,因而就可以使用真正的多線程。
上面都是理論,接下來(lái)實(shí)戰(zhàn)看看實(shí)際效果是否符合理論
2、代碼練習(xí)
"""多線程多進(jìn)程模擬執(zhí)行效率""" from multiprocessing import Pool from threading import Thread import time, math def simulation_IO(a): """模擬IO操作""" time.sleep(3) def simulation_compute(a): """模擬計(jì)算密集型任務(wù)""" for i in range(int(1e7)): math.sin(40) + math.cos(40) return def normal_func(func): """普通方法執(zhí)行效率""" for i in range(6): func(i) return def mp(func): """進(jìn)程池中的map方法""" with Pool(processes=6) as p: res = p.map(func, list(range(6))) return def asy(func): """進(jìn)程池中的異步執(zhí)行""" with Pool(processes=6) as p: result = [] for j in range(6): a = p.apply_async(func, args=(j, )) result.append(a) res = [j.get() for j in result] def thread(func): """多線程方法""" threads = [] for j in range(6): t = Thread(target=func, args=(j, )) threads.append(t) t.start() for t in threads: t.join() def showtime(f, func, name): """ 計(jì)算并展示函數(shù)的運(yùn)行時(shí)間 :param f: 多進(jìn)程和多線程的方法 :param func: 多進(jìn)程和多線程方法中需要傳入的函數(shù) :param name: 方法的名字 :return: """ start_time = time.time() f(func) print(f"{name} time: {time.time() - start_time:.4f}s") def main(func): """ 運(yùn)行程序的主函數(shù) :param func: 傳入需要計(jì)算時(shí)間的函數(shù)名 """ showtime(normal_func, func, "normal") print() print("------ 多進(jìn)程 ------") showtime(mp, func, "map") showtime(asy, func, "async") print() print("----- 多線程 -----") showtime(thread, func, "thread") if __name__ == "__main__": print("------------ 計(jì)算密集型 ------------") func = simulation_compute main(func) print() print() print() print("------------ IO 密集型 ------------") func = simulation_IO main(func)
3、運(yùn)行結(jié)果
線性執(zhí)行 | 多進(jìn)程(map) | 多進(jìn)程(async) | 多線程 | |
---|---|---|---|---|
計(jì)算密集型 | 16.0284s | 3.5236s | 3.4367s | 15.2142s |
IO密集型 | 18.0201s | 3.0945s | 3.0809s | 3.0041s |
從表格中很明顯的可以看出:
- 計(jì)算密集型任務(wù)的速度:多進(jìn)程 >多線程> 單進(jìn)程/線程
- IO密集型任務(wù)速度: 多線程 > 多進(jìn)程 > 單進(jìn)程/線程。
所以,針對(duì)計(jì)算密集型任務(wù)使用多進(jìn)程,針對(duì)IO密集型任務(wù)使用多線程
到此這篇關(guān)于python 多線程與多進(jìn)程效率測(cè)試 的文章就介紹到這了,更多相關(guān)python 多線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django框架實(shí)現(xiàn)的普通登錄案例【使用POST方法】
這篇文章主要介紹了Django框架實(shí)現(xiàn)的普通登錄案例,結(jié)合實(shí)例形式分析了Django框架使用POST方法進(jìn)行頁(yè)面登錄、校驗(yàn)等相關(guān)操作技巧,需要的朋友可以參考下2019-05-05解決Keras TensorFlow 混編中 trainable=False設(shè)置無(wú)效問(wèn)題
這篇文章主要介紹了解決Keras TensorFlow 混編中 trainable=False設(shè)置無(wú)效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06多版本python的pip 升級(jí)后, pip2 pip3 與python版本失配解決方法
在本篇文章里小編給大家整理的是關(guān)于多版本python的pip 升級(jí)后, pip2 pip3 與python版本失配的解決方法內(nèi)容,需要的朋友們學(xué)習(xí)下。2019-09-09python使用pytest接口自動(dòng)化測(cè)試的使用
這篇文章主要介紹了python使用pytest接口自動(dòng)化測(cè)試的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Python Pygame實(shí)戰(zhàn)之趣味籃球游戲的實(shí)現(xiàn)
這篇文章主要為大家分享了一個(gè)基于Python和Pygame實(shí)現(xiàn)的一個(gè)趣味籃球游戲,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-04-04Python3 Tkinkter + SQLite實(shí)現(xiàn)登錄和注冊(cè)界面
這篇文章主要為大家詳細(xì)介紹了Python3 Tkinkter + SQLite實(shí)現(xiàn)登錄和注冊(cè)界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11