此文三個目的,不能光意淫概念誤入歧途,有的人以為得概念一套一套的,其實並不是想的那樣,實踐對比才能出真知,要尊重實踐。
此文使用各種網絡請求庫和各種並發模式和各種大小的線程池來測試請求50000次一個內容源碼很小的百度靜態頁面,分別測試http和https
https://www.baidu.com/content-search.xml
http://www.baidu.com/content-search.xml
網頁內容很小,(基本可以排除認為請求得慢,耍賴說是網速帶寬差造成的)。
1.總結一下python的各種網絡請求庫的性能,包括urllib3 和requests和aiohttp
2.總結一下 多線程 asyncio gevent的 並發效率
3.4核cpu情況下對比200線程池並發數量和 9線程池(2 * 4 +1)並發效率。
測試截圖如下,nb_log把print時間自動打印出來,方便控制台搜索每秒運行多少次,一定要import nb_log。

測試方案1:

urllib3 + ThreadPoolExecutor 200線程池 +請求連接池 + 請求 https
平均每秒請求完成 750次。
測試方案2

requests + ThreadPoolExecutor 200線程池 +請求連接池 + 請求 https
平均每秒請求完成310次。
測試方案3

urllib3 + gevent 200並發 + 連接池 + 請求https
平均每秒秒請求完成270次。
測試方案4

urllib3 + 線程池 200並發 + 連接池 + 請求http (注意是http,不是https,https會執行更多的代碼路徑消耗更高的cpu)
平均每秒秒請求完成1300次。
測試方案5

requests + 線程池 200並發 + 連接池 + 請求http (注意是http,不是https)
平均每秒秒請求完成330次。
測試方案6

urllib3 + gevent 200並發 + 連接池 + 請求http (注意是http,不是https)
平均每秒秒請求完成580次。
測試方案7

urllib3 + 線程池 200並發 + 不使用請求連接池 + 請求https (注意是https,不是http)
平均每秒秒請求完成580次。
測試方案8

requests + 線程池 200並發 + 不使用請求連接池 + 請求https (注意是https,不是http)
平均每秒秒請求完成120次。
測試方案9

aiohttp + asyncio 200並發 + 使用請求連接池 + 請求https (注意是https,不是http)
平均每秒秒請求完成990次。
測試方案10

aiohttp + asyncio 200並發 + 使用請求連接池 + 請求http (注意是http,不是https)
平均每秒秒請求完成1080次。
測試方案11

aiohttp + asyncio 200並發 + 不使用請求連接池 + 請求http (注意不使用連接池)
平均每秒秒請求完成400次。
測試方案12

aiohttp + asyncio 200並發 + 不使用請求連接池 + 請求https (注意不使用連接池)
平均每秒秒請求完成170次。
綜上所述, 請求http比https快很多
連接池比不使用連接池快很多。
gevent 比線程池慢。
urllib3 比requests快很多。
asyncio + aiohttp 比線程池 + urllib3 效率差不多,絕對不會出現asyncio吊打多線程幾十倍,無需過於理論上擔憂線程切換消耗大量資源,這只是個理論,實際真實場景下不會強很多,而且同步編程簡單很多。
具體原因是每種場景運行次數差別,是因為消耗的cpu單核達到100%了,單核單進程無法再提高速度了,除非是花10萬定制一個10ghz主頻的cpu液氮散熱。
requests包get請求http的url,實際執行的代碼是24000行,urllib3包get 請求http的url實際執行11000行代碼,因為urllib3實際運行的代碼行數只有requests包的一半以下,所以urllib3性能明顯好於requests。
具體怎么知道一個函數運行的背后實際執行多少行代碼呢,使用pycharm打斷點 一行一行慢慢運行慢慢數是可以的,但這樣會數到你懷疑人生,使用pip install pysnooper_click_able,然后把裝飾器加在需要 分析的 函數就可以統計出來代碼運行軌跡和實際執行的總行數。pysnooper_click_able 是神級別黑科技裝飾器。
來計算一下執行的 代碼實際行數,一次urllib3.get 需要運行1萬2000行代碼 ,每秒運行了1000次請求,那就是相當於每秒運行了 1千萬 行python代碼,所以訥還可以了。那些對性能一無所知的小白以為單進程可以每秒請求100萬次 url,完完全全的錯誤了1000倍,因為是沒有 使用 pysnooper_click_able 分析代碼執行行數,以為發一個url請求只需要執行10幾行python代碼,大錯特錯。如果有人認為單進程能每秒請求1萬次url,不管你用什么異步並發還是線程並發實現的,我們賭1萬人民幣可以。
在4核機器上親求一個非常快的接口,4線程和200線程相比,200線程快很多。如果接口響應耗時長,例如需要耗時1秒,200線程請求完成5萬次的時間遠遠遠遠小於4線程請求耗時,無需過濾線程多了切換耗資源。
所以大膽點,只要不是純計算的,有io超過0.5秒的開200個線程,大膽點,不要怕cpu爆炸了,有的買了mac筆記本的人真的害怕開很多線程總是擔心線程開多了,筆記本會爆炸會損害,不用擔心,炸了我陪你一個。
再說這么愛惜筆記本這么小氣的人,為什么非要花1萬3買蘋果筆記本訥,5800u 8核16線程 + 32g + depping20 系統的筆記本才4000多元不行嗎,跑代碼的性能開16進程 + 每個進程內部開200個線程,跑起代碼來,運行速度遠遠的暴擊不敢開多線程怕mac筆記本爆炸的人。
