上下文切換在所有運(yùn)行的任務(wù)間公平地共享 CPU 所需的工作,稱為上下文切換,能夠影響應(yīng)用程序的性能 。對(duì)同步應(yīng)用程序來(lái)說(shuō),這項(xiàng)工作是由操作系統(tǒng)完成的,而且基本上是一個(gè)黑箱,不需要配置或微調(diào)選項(xiàng) 。對(duì)異步應(yīng)用程序來(lái)說(shuō),上下文切換是由循環(huán)完成的 。
默認(rèn)的循環(huán)實(shí)現(xiàn)由asyncio提供,是用 Python 編寫(xiě)的,效率不是很高 。而 uvloop 包提供了一個(gè)備選的循環(huán)方案,其中部分代碼是用 C 編寫(xiě)的來(lái)實(shí)現(xiàn)更好的性能 。Gevent 和 Meinheld 所使用的事件循環(huán)也是用 C 編寫(xiě)的 。Eventlet 用的是 Python 編寫(xiě)的循環(huán) 。
高度優(yōu)化的異步循環(huán)比操作系統(tǒng)在進(jìn)行上下文切換方面更有效率,但根據(jù)我的經(jīng)驗(yàn),要想看到實(shí)際的效率提升,你運(yùn)行的并發(fā)量必須非常大 。對(duì)于大部分應(yīng)用程序,我不認(rèn)為同步和異步上下文切換之間的性能差距有多明顯 。
擴(kuò)展性我認(rèn)為異步更快這個(gè)神話的來(lái)源是,異步應(yīng)用程序通常會(huì)更有效地使用 CPU、能更好地進(jìn)行擴(kuò)展并且擴(kuò)展方式比同步更靈活 。
如果上面示意圖中的同步服務(wù)器同時(shí)收到 100 個(gè)請(qǐng)求,想一下會(huì)發(fā)生什么 。這個(gè)服務(wù)器同時(shí)最多只能處理 4 個(gè)請(qǐng)求,因此大部分請(qǐng)求會(huì)停留在一個(gè)隊(duì)列中等待,直到它們被分配一個(gè) worker 。
與之形成對(duì)比的是,異步服務(wù)器會(huì)立即創(chuàng)建 100 個(gè)任務(wù)(或者使用混合模式的話,在 4 個(gè)異步 worker 上每個(gè)創(chuàng)建 25 個(gè)任務(wù)) 。使用異步服務(wù)器,所有請(qǐng)求都會(huì)立即開(kāi)始處理而不用等待(盡管公平地說(shuō),這種方案也還會(huì)有其它瓶頸會(huì)減慢速度,例如對(duì)活躍的數(shù)據(jù)庫(kù)連接的限制) 。
如果這 100 個(gè)任務(wù)主要使用 CPU,那么同步和異步方案會(huì)有相似的性能,因?yàn)槊總€(gè) CPU 運(yùn)行的速度是固定的,Python 執(zhí)行代碼的速度總是相同的,應(yīng)用程序要完成的工作也是相同的 。但是,如果這些任務(wù)需要做很多 I/O 操作,那么同步服務(wù)器只能處理 4 個(gè)并發(fā)請(qǐng)求而不能實(shí)現(xiàn) CPU 的高利用率 。而另一方面,異步服務(wù)器會(huì)更好地保持 CPU 繁忙,因?yàn)樗遣⑿械剡\(yùn)行所有這 100 個(gè)請(qǐng)求 。
你可能會(huì)想,為什么你不能運(yùn)行 100 個(gè)同步 worker,那樣,這兩個(gè)服務(wù)器就會(huì)有相同的并發(fā)能力 。要注意,每個(gè) worker 需要自己的 Python 解釋器以及與之相關(guān)聯(lián)的所有資源,再加上一份單獨(dú)的應(yīng)用程序拷貝及其資源 。你的服務(wù)器和應(yīng)用程序的大小將決定你可以運(yùn)行多少個(gè) worker 實(shí)例,但通常這個(gè)數(shù)字不會(huì)很大 。另一方面,異步任務(wù)非常輕量,都運(yùn)行在單個(gè) worker 進(jìn)程的上下文中,因此具有明顯優(yōu)勢(shì) 。
綜上所述,只有如下場(chǎng)景時(shí),我們可以說(shuō)異步可能比同步快:
- 存在高負(fù)載(沒(méi)有高負(fù)載,訪問(wèn)的高并發(fā)性就沒(méi)有優(yōu)勢(shì))
- 任務(wù)是 I/O 綁定的(如果任務(wù)是 CPU 綁定的,那么超過(guò) CPU 數(shù)目的并發(fā)并沒(méi)有幫助)
- 你查看單位時(shí)間內(nèi)的平均請(qǐng)求處理數(shù) 。如果你查看百思特網(wǎng)單個(gè)請(qǐng)求的處理時(shí)間,你不會(huì)看到有很大差別,甚至異步可能更慢,因?yàn)楫惒接懈嗖l(fā)的任務(wù)在爭(zhēng)奪 CPU 。
- 異步應(yīng)用程序只有在高負(fù)載下才會(huì)比同步應(yīng)用程序做得更好
- 多虧了 greenlets,即使你用一般方式寫(xiě)代碼并使用 Flask 或 Django 之類的傳統(tǒng)框架,也能從異步中受益 。
作者介紹:
Miguel Grinberg 是一名軟件工程師、攝影師和電影制作人,住在愛(ài)爾蘭的德羅赫拉 。你可以在 Facebook 、 Google 、 LinkedIn 、 Github 和 Twitter 他 。
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問(wèn)題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專業(yè)人士給予相關(guān)指導(dǎo)!
「愛(ài)刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助:- 起步絕不會(huì)熄火的訣竅 熄火是什么
- 一些風(fēng)水常識(shí) 風(fēng)水是什么
- 我的火花可能是 火花是什么
- 單推是什么意思 推是什么意思
- 子陽(yáng)名字的含義是什么 子的意思是什么
- 解說(shuō)2者區(qū)別與聯(lián)系 無(wú)線ap和路由器的區(qū)別是什么
- 規(guī)格是什么意思?跟型號(hào)有區(qū)別嗎? 型號(hào)是什么意思
- 朝著目標(biāo)努力的好句子 目標(biāo)是什么意思
- 什么叫插排 插座是什么
- 大學(xué)生簽三方協(xié)議注意事項(xiàng) 三方是什么
