少妇脱了内裤让我添,久久久久亚洲精品无码网址蜜桃,性色av免费观看,久久人妻av无码中文专区

分享

阿里巴巴楊群:高并發(fā)場景下Python的性能挑戰(zhàn)

 車?yán)遄覸 2019-08-06

4月13日,在CSDN主辦的“2019 Python開發(fā)者日”大會(huì)上,阿里云數(shù)據(jù)庫專家楊群分享了《高并發(fā)場景下Python的性能挑戰(zhàn)》的主題演講。

以下為演講整理,文章略有刪減:

性能問題

▌(一)GIL

為什么大家都說Python慢?最主要的原因是全局解釋器鎖。今天講的Python是官方的C版Python。CPython在創(chuàng)建變量時(shí),首先對變量分配內(nèi)存,然后開始計(jì)數(shù)變量的數(shù)量,大家提出稱之為“引用計(jì)數(shù)”。在引用計(jì)數(shù)變?yōu)?時(shí),從系統(tǒng)中釋放變量的內(nèi)存。如果多個(gè)線程同時(shí)對這個(gè)計(jì)數(shù)做操作,線程不安全,會(huì)導(dǎo)致很多問題。

綜合垃圾回收機(jī)制問題,CPython引入了GIL,同一個(gè)時(shí)刻在一個(gè)進(jìn)程允許一個(gè)線程使用解釋器,意味著單進(jìn)程下Python多線程的性能沒有那么好。這樣做的好處在于能夠避免死鎖和數(shù)據(jù)用戶安全方面的問題。

Python有三種線程狀態(tài):Idle、Running、Failed GIL Acquire。曾經(jīng)有人對GIL的性能影響做了兩個(gè)測試。第一個(gè)測試案例是兩個(gè)CPU密集線程,代碼運(yùn)行過程的大部分狀態(tài)是Failed GIL Acquire,兩個(gè)線程的運(yùn)行沒有達(dá)到雙核的效果。

第二個(gè)案例是IO密集型的線程。仔細(xì)分析發(fā)現(xiàn),IO沒有達(dá)到想象的預(yù)期效果。所以IO密集型和CPU密集型同時(shí)存在時(shí),IO密集型未必達(dá)到想要的運(yùn)算速度,我們要區(qū)分好IO密集型和CPU密集型的服務(wù)。

▌(二)解釋器

CPython要首先生成pcy字節(jié)碼序列,之后才能被CPU理解,所以較慢。JAVA、.NET也有中間的翻譯,但因?yàn)镴AVA和.NET使用即時(shí)編輯(JIT),使用JIT可以檢測哪些代碼執(zhí)行得比較多,意味著計(jì)算機(jī)應(yīng)用程序需要重復(fù)做一件事情的時(shí)候它就會(huì)更快。

▌(三)動(dòng)態(tài)語言

Python是動(dòng)態(tài)語言類型,我們在做類型轉(zhuǎn)化或者比較的時(shí)候比較耗時(shí),因?yàn)樽x取、寫入變量或者引用變量時(shí)會(huì)進(jìn)行檢查。靜態(tài)類型語言沒有這么高的靈活性,但它已經(jīng)規(guī)定好了內(nèi)存中的狀態(tài),所以很快。

Python這么慢,我們?yōu)槭裁催€要用它?一是用Python優(yōu)雅、簡潔。二是大多數(shù)應(yīng)用場景時(shí),GIL或者解釋器帶來的性能未必是我們所擔(dān)心的,比如科學(xué)計(jì)算或者平常做一些數(shù)據(jù)分析或小應(yīng)用時(shí)不會(huì)考慮到這個(gè)問題。

服務(wù)選型

640?wx_fmt=png

             這是市面上常用的web框架針對Python的領(lǐng)域做服務(wù)選型分析的框架。無論使用什么web框架,在web服務(wù)中都會(huì)選擇多進(jìn)程。一方面考慮到服務(wù)需要一定的可用性,需要多進(jìn)程來保證減少服務(wù)可用性的影響。另外,多個(gè)進(jìn)程意味著多個(gè)解釋器,多個(gè)解釋器意味著我們盡量減少GIL帶來的性能影響。

640?wx_fmt=png

這是常見web服務(wù)的方法,前端的LoadBalancer,大家可能會(huì)選擇常見的Nginx、apache或者云服務(wù)的SLB。

異步IO框架的選擇是大家都關(guān)心的一個(gè)問題。GIL如果是IO密集型,我們用異步能夠做到很快。但是它有很適合的應(yīng)用場景,比如不想做Nginxluv插件,作為高性能的擴(kuò)展方案,那就用tornado來寫,如果內(nèi)部代碼全是異步的IO操作,它是非常好的,可以組裝自己的邏輯,比如積數(shù)之類的都可以放在tornado里來做,性能可以得到保障。

另外,PyPy是Python的Just in time 編譯器,性能一般要比CPython解釋器至少好3倍。但是它和JIT編譯器一樣有啟動(dòng)慢的特點(diǎn),所以適合對重啟不是很敏感的服務(wù)。它的問題是不支持C擴(kuò)展的Python庫。

性能瓶頸分析

在現(xiàn)實(shí)業(yè)務(wù)開發(fā)中,最主要的是依靠業(yè)務(wù)日志分析,考慮我們的業(yè)務(wù)鏈路中是否存在網(wǎng)絡(luò)耗時(shí)。對一些任務(wù)日志可以用AWK或者unit等,去分析出來哪些接口訪問量比較多、耗時(shí)嚴(yán)重的,使用Cprofile等工具分析問題存在哪里,然后再找到合適的優(yōu)化方向。

640?wx_fmt=png

這是一個(gè)簡單的Cprofile例子,執(zhí)行def1、def2、def3,去分析一下它的耗時(shí)情況。

640?wx_fmt=png

上面的代碼中有多個(gè)函數(shù)的執(zhí)行。可以看到,最后一次的運(yùn)行耗時(shí)是237毫秒。當(dāng)然,對于profile也可以輸出pstat格式的數(shù)據(jù),大家能通過可視化清楚的看到自己函數(shù)耗時(shí)占比。

優(yōu)化方法

▌(一)原則

第一,優(yōu)化時(shí)一定要靠數(shù)據(jù)說話。即使需要犧牲一次迭代去更新一下,也要把數(shù)據(jù)羅列出來,使之有理有據(jù)。我們優(yōu)化的原則主要有四點(diǎn):一是用數(shù)據(jù)說話,數(shù)據(jù)不只是優(yōu)化的原因,也是優(yōu)化的方向,把指標(biāo)達(dá)到一定水準(zhǔn),目的才達(dá)到了;第二,不要過早優(yōu)化或過度優(yōu)化。否則有可能出現(xiàn)業(yè)務(wù)偏差;第三,深入理解業(yè)務(wù)。對產(chǎn)品更加負(fù)責(zé);第四,選擇好的衡量標(biāo)準(zhǔn),比如CPU利用率降到多少了。

▌(二)IO密集型

如果是IO密集型的服務(wù),使用多線程實(shí)際比單線程的性能提高很多。但是如果大量IO操作都比較耗時(shí),它的性能未必像想象中那么好。這種情況下建議批量操作,或者改為協(xié)程,網(wǎng)絡(luò)帶寬性能會(huì)帶來很大的提升。此外,減少IO操作也是可行方案。

▌(三)CPU密集型

多線程顯然已經(jīng)不適用于CPU密集型的服務(wù),因?yàn)轭l繁的GIL爭搶會(huì)導(dǎo)致序性能大幅度下降。多進(jìn)程其實(shí)很適合CPU密集型服務(wù)。對于CPU密集型的服務(wù),為了減少解釋器的損耗 ,最好可以適用C的擴(kuò)展庫來提高程序性能,能夠一定程度緩解類型轉(zhuǎn)換帶來的性能損耗 ,而且可以大幅度提高基礎(chǔ)庫的運(yùn)行速度。

▌(四)緩存

緩存一直是系統(tǒng)性能優(yōu)化的利器,這對Python是架構(gòu)性的東西,可能跟語言的相關(guān)性沒有那么大。但是Python的編程方法對緩存代碼改造是非常便利的。

640?wx_fmt=png

這是緩存的例子,這個(gè)業(yè)務(wù)邏輯很簡單,在現(xiàn)有的生產(chǎn)模型里比較常用。

640?wx_fmt=png

這是一個(gè)有緩存的函數(shù),我們在性能調(diào)優(yōu)時(shí)需要?jiǎng)討B(tài)去允許開關(guān)函數(shù)不緩存,必須按照原來的方式執(zhí)行一遍才能拿到結(jié)果。這里有一個(gè)計(jì)算緩存過程,mode是我們開發(fā)的模式,可以在函數(shù)動(dòng)態(tài)的取mode,達(dá)到開關(guān)的值。我們可以通過這個(gè)開關(guān)去讓函數(shù)得到它執(zhí)行的方式。

另外,我們在存儲(chǔ)序列化數(shù)據(jù)時(shí)最好使用高性能的庫,比如cPickle,cPickle雖然比pickle,但是沒有cJSON快。可以給存儲(chǔ)層、DB層、計(jì)算的函數(shù)層、應(yīng)用層都加上緩存,但是在Python應(yīng)用程序之外也有很多架設(shè)高速緩存的方法。

多層緩存雖然是一個(gè)架構(gòu)緩存,但是Python開發(fā)做擴(kuò)展性應(yīng)用時(shí),用戶體驗(yàn)是非常好的,簡短的代碼開發(fā)就可以完成通用功能,而且里面的語言不用動(dòng)。

▌(五)懶加載

640?wx_fmt=png

       還有一些常用的方法,比如懶加載。這是常用的Lazy單例,調(diào)用一次之后就不再調(diào)用了,以后拿到的是初始化好的。

▌(六)一些技巧

640?wx_fmt=png

對于generator需要謹(jǐn)慎對待。 對于循環(huán)遍歷,比如遍歷10萬個(gè)數(shù)據(jù),generator有可能更慢一些,這種東西是需要分場合的。如果在循環(huán)中不需要把所有列表生成出來,那么速度會(huì)稍微快一些。

640?wx_fmt=png

這是一個(gè)命名空間問題。第一種狀況可能更簡單一些,但是它是147毫秒,第二種狀況是把循環(huán)函數(shù)里,快了1倍時(shí)間。這是因?yàn)镻ython在執(zhí)行代碼時(shí)遇到了range。對于第一種,Python首先會(huì)在本地的變量里找這個(gè)range,如果沒有找到會(huì)去gloabl變量里找range。

對于第二種,range的查找不需要再走gloabl,它走的是load-const,這是一個(gè)很快的過程。有些由于空間導(dǎo)致的性能微小的差距,執(zhí)行少量數(shù)據(jù)時(shí)看不出來,但是大量數(shù)據(jù)時(shí)是非常明顯的。

總結(jié)

Python這種便利的特性給我們帶來很大的開發(fā)優(yōu)勢:

數(shù)據(jù)分析是第一位的,要去優(yōu)化自己的Python服務(wù)。

第二,需要合理的測試環(huán)境,不要因?yàn)樾阅苷{(diào)優(yōu)而影響增加的服務(wù)穩(wěn)定性或者出現(xiàn)故障。

第三,要有的放矢,我們有時(shí)面對更多服務(wù)拆分或微服務(wù)化,對架構(gòu)說不定有更多好處。比如把IO密集型服務(wù)和CPU密集型服務(wù)分開做,在前端使用IO密集型的操作。將所有的請求都集中在對外的入口,這樣對外服務(wù)的性能會(huì)得到很大的提高,因?yàn)樾阅軌毫Χ挤稚⒌礁鱾€(gè)微服務(wù)里了,而同樣的性能得到了最大的保障。大家可以多鉆研一下,掌握一些技巧。

謝謝大家。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    主站蜘蛛池模板: 亚洲色大成网站www看下面| 国产成人理论无码电影网| 国产精品一区二区高清在线| 欧美亚洲精品中文字幕乱码| 中字幕视频在线永久在线观看免费| 日本顶级metart裸体全部| 亚洲综合国产在不卡在线| 高潮抽搐潮喷毛片在线播放| 亚洲爆乳无码一区二区三区| 高清国产精品人妻一区二区| 成人国产mv免费视频| 欧美综合区自拍亚洲综合图| 欧洲精品免费一区二区三区| 日韩av一国产av一中文字慕| 日本一卡二卡不卡视频查询| 国产乱子伦视频在线观看| 国产精品av一区二区三区不卡蜜| 精品亚洲欧美视频在线观看| 久久国内精品一区二区三区| 久久国产成人午夜av影院| 久久99久久99精品免视看动漫| 性高朝大尺度少妇大屁股| 国产精品无码不卡一区二区三区| 狠狠婷婷综合久久久久久| 少妇高潮惨叫久久久久久| 亚洲精品拍拍央视网出文| 亚洲狠狠成人网| 国产做a爰片久久毛片a片美国| 欧洲美熟女乱av亚洲一区| 国产成人精品免费视频app软件| 国产乱子伦视频一区二区三区| 国产偷国产偷亚州清高app| 两个男人吮她的花蒂和奶水视频| 亚洲国产长腿丝袜av天堂| 色yeye香蕉凹凸视频在线观看| 国产性一交一乱一伦一色一情| 亚洲av成人一区二区三区av| 久久久精品人妻久久影视| 97精品国产手机| 日韩人妻无码中文字幕视频| 精品人妻潮喷久久久又裸又黄|