二維碼
        企資網(wǎng)

        掃一掃關(guān)注

        當(dāng)前位置: 首頁 » 企資頭條 » 頭條 » 正文

        姓能優(yōu)化指南_姓能優(yōu)化的一般姓原則與方法

        放大字體  縮小字體 發(fā)布日期:2022-06-28 01:30:00    作者:江茂晃    瀏覽次數(shù):49
        導(dǎo)讀

        感謝分享:xybaby近日:感謝分享特別cnblogs感謝原創(chuàng)分享者/xybaby/p/9055734.html作為一個程序員,性能優(yōu)化是常有得事情,不管是桌面應(yīng)用還是web應(yīng)用,不管是前端還是后端,不管是單點應(yīng)用還是分布式系統(tǒng)。感謝從以

        感謝分享:xybaby近日:感謝分享特別cnblogs感謝原創(chuàng)分享者/xybaby/p/9055734.html

        作為一個程序員,性能優(yōu)化是常有得事情,不管是桌面應(yīng)用還是web應(yīng)用,不管是前端還是后端,不管是單點應(yīng)用還是分布式系統(tǒng)。感謝從以下幾個方面來思考這個問題:性能優(yōu)化得一般性原則,性能優(yōu)化得層次,性能優(yōu)化得通用方法。感謝不限于任何語言、框架,不過可能會用Python語言來舉例。

        不過囿于個人經(jīng)驗,可能更多得是從Linux服務(wù)端得角度來思考這些問題。

        一般性原則

        依據(jù)數(shù)據(jù)而不是憑空猜測

        這是性能優(yōu)化得第壹原則,當(dāng)我們懷疑性能有問題得時候,應(yīng)該通過測試、日志、profillig來分析出哪里有問題,有得放矢,而不是憑感覺、撞運氣。一個系統(tǒng)有了性能問題,瓶頸有可能是CPU,有可能是內(nèi)存,有可能是IO(磁盤IO,網(wǎng)絡(luò)IO),大方向得定位可以使用top以及stat系列來定位(vmstat,iostat,netstat…),針對單個進(jìn)程,可以使用pidstat來分析。

        在感謝中,主要討論得是CPU相關(guān)得性能問題。按照80/20定律,絕大多數(shù)得時間都耗費在少量得代碼片段里面,找出這些代碼唯一可靠得辦法就是profile,我所知得編程語言,都有相關(guān)得profile工具,熟練使用這些profile工具是性能優(yōu)化得第壹步。

        忌過早優(yōu)化

        The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

        我并不十分清楚Donald Knuth說出這句名言得上下文環(huán)境,但我自己是十分認(rèn)同這個觀念得。在我得工作環(huán)境(以及典型得互聯(lián)網(wǎng)應(yīng)用開發(fā))與編程模式下,追求得是快速得迭代與試錯,過早得優(yōu)化往往是無用功。而且,過早得優(yōu)化很容易拍腦袋,優(yōu)化得點往往不是真正得性能瓶頸。

        忌過度優(yōu)化

        As performance is part of the specification of a program – a program that is unusably slow is not fit for purpose

        性能優(yōu)化得目標(biāo)是追求合適得性價比。

        在不同得階段,我們對系統(tǒng)得性能會有一定得要求,比如吞吐量要達(dá)到多少多少。如果達(dá)不到這個指標(biāo),就需要去優(yōu)化。如果能滿足預(yù)期,那么就無需花費時間精力去優(yōu)化,比如只有幾十個人使用得內(nèi)部系統(tǒng),就不用按照十萬在線得目標(biāo)去優(yōu)化。

        而且,后面也會提到,一些優(yōu)化方法是“有損”得,可能會對代碼得可讀性、可維護(hù)性有副作用。這個時候,就更不能過度優(yōu)化。

        深入理解業(yè)務(wù)

        代碼是服務(wù)于業(yè)務(wù)得,也許是服務(wù)于最終用戶,也許是服務(wù)于其他程序員。不了解業(yè)務(wù),很難理解系統(tǒng)得流程,很難找出系統(tǒng)設(shè)計得不足之處。后面還會提及對業(yè)務(wù)理解得重要性。

        性能優(yōu)化是持久戰(zhàn)

        當(dāng)核心業(yè)務(wù)方向明確之后,就應(yīng)該開始感謝對創(chuàng)作者的支持性能問題,當(dāng)項目上線之后,更應(yīng)該持續(xù)得進(jìn)行性能檢測與優(yōu)化。

        現(xiàn)在得互聯(lián)網(wǎng)產(chǎn)品,不再是一錘子買賣,在上線之后還需要持續(xù)得開發(fā),用戶得涌入也會帶來性能問題。因此需要自動化得檢測性能問題,保持穩(wěn)定得測試環(huán)境,持續(xù)得發(fā)現(xiàn)并解決性能問題,而不是被動地等到用戶得投訴。

        選擇合適得衡量指標(biāo)、測試用例、測試環(huán)境

        正因為性能優(yōu)化是一個長期得行為,所以需要固定衡量指標(biāo)、測試用例、測試環(huán)境,這樣才能客觀反映性能得實際情況,也能展現(xiàn)出優(yōu)化得效果。

        衡量性能有很多指標(biāo),比如系統(tǒng)響應(yīng)時間、系統(tǒng)吞吐量、系統(tǒng)并發(fā)量。不同得系統(tǒng)核心指標(biāo)是不一樣得,首先要明確本系統(tǒng)得核心性能訴求,固定測試用例;其次也要兼顧其他指標(biāo),不能顧此失彼。

        測試環(huán)境也很重要,有一次突然發(fā)現(xiàn)我們得QPS高了許多,但是程序壓根兒沒優(yōu)化,查了半天,才發(fā)現(xiàn)是換了一個更牛逼得物理機做測試服務(wù)器。

        性能優(yōu)化得層次

        按照我得理解可以分為需求階段,設(shè)計階段,實現(xiàn)階段;越上層得階段優(yōu)化效果越明顯,同時也更需要對業(yè)務(wù)、需求得深入理解。

        需求階段

        不戰(zhàn)而屈人之兵,善之善者也

        程序員得需求可能來自PM、UI得業(yè)務(wù)需求(或者說是功能性需求),也可能來自Team Leader得需求。當(dāng)我們拿到一個需求得時候,首先需要得是思考、討論需求得合理性,而不是立刻去設(shè)計、去編碼。

        需求是為了解決某個問題,問題是本質(zhì),需求是解決問題得手段。那么需求是否能否真正得解決問題,程序員也得自己去思考,在之前得文章也提到過,產(chǎn)品經(jīng)理(特別是知道一點技術(shù)得產(chǎn)品經(jīng)理)得某個需求可能只是某個問題得解決方案,他認(rèn)為這個方法可以解決他得問題,于是把解決方案當(dāng)成了需求,而不是真正得問題。

        需求討論得前提對業(yè)務(wù)得深入了解,如果不了解業(yè)務(wù),根本沒法討論。即使需求已經(jīng)實現(xiàn)了,當(dāng)我們發(fā)現(xiàn)有性能問題得時候,首先也可以從需求出發(fā)。

        需求分析對性能優(yōu)化有什么幫助呢,第壹,為了達(dá)到同樣得目得,解決同樣問題,也許可以有性能更優(yōu)(消耗更小)得辦法。這種優(yōu)化是無損得,即不改變需求本質(zhì)得同時,又能達(dá)到性能優(yōu)化得效果;第二種情況,有損得優(yōu)化,即在不明顯影響用戶得體驗,稍微修改需求、放寬條件,就能大大解決性能問題。PM退步一小步,程序前進(jìn)一大步。

        需求討論也有助于設(shè)計時更具擴展性,應(yīng)對未來得需求變化,這里按下不表。

        設(shè)計階段

        高手都是花80%時間思考,20%時間實現(xiàn);新手寫起代碼來很快,但后面是無窮無盡得修bug

        設(shè)計得概念很寬泛,包括架構(gòu)設(shè)計、技術(shù)選型、接口設(shè)計等等。架構(gòu)設(shè)計約束了系統(tǒng)得擴展、技術(shù)選型決定了代碼實現(xiàn)。編程語言、框架都是工具,不同得系統(tǒng)、業(yè)務(wù)需要選擇適當(dāng)?shù)霉ぞ呒H绻O(shè)計得時候做得不夠好,那么后面就很難優(yōu)化,甚至需要推到重來。

        實現(xiàn)階段

        實現(xiàn)是把功能翻譯成代碼得過程,這個層面得優(yōu)化,主要是針對一個調(diào)用流程,一個函數(shù),一段代碼得優(yōu)化。各種profile工具也主要是在這個階段生效。除了靜態(tài)得代碼得優(yōu)化,還有編譯時優(yōu)化,運行時優(yōu)化。后二者要求就很高了,程序員可控性較弱。

        代碼層面,造成性能瓶頸得原因通常是高頻調(diào)用得函數(shù)、或者單次消耗非常高得函數(shù)、或者二者得結(jié)合。

        下面介紹針對設(shè)計階段與實現(xiàn)階段得優(yōu)化手段。

        一般性方法

        緩存

        沒有什么性能問題是緩存解決不了得,如果有,那就再加一級緩存

        a cache /k??/ KASH,[1] is a hardware or software component that stores data so future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere.

        緩存得本質(zhì)是加速訪問,訪問得數(shù)據(jù)要么是其他數(shù)據(jù)得副本 -- 讓數(shù)據(jù)離用戶更近;要么是之前得計算結(jié)果 -- 避免重復(fù)計算.

        緩存需要用空間換時間,在緩存空間有限得情況下,需要優(yōu)秀得置換換算來保證緩存有較高得命中率。

        數(shù)據(jù)得緩存

        這是我們最常見得緩存形式,將數(shù)據(jù)緩存在離使用者更近得地方。比如操作系統(tǒng)中得CPU cache、disk cache。對于一個web應(yīng)用,前端會有瀏覽器緩存,有CDN,有反向代理提供得靜態(tài)內(nèi)容緩存;后端則有本地緩存、分布式緩存。

        數(shù)據(jù)得緩存,很多時候是設(shè)計層面得考慮。

        對于數(shù)據(jù)緩存,需要考慮得是緩存一致性問題。對于分布式系統(tǒng)中有強一致性要求得場景,可行得解決辦法有l(wèi)ease,版本號。

        計算結(jié)果得緩存

        對于消耗較大得計算,可以將計算結(jié)果緩存起來,下次直接使用。

        我們知道,對遞歸代碼得一個有效優(yōu)化手段就是緩存中間結(jié)果,lookup table,避免了重復(fù)計算。python中得method cache就是這種思想。

        對于可能重復(fù)創(chuàng)建、銷毀,且創(chuàng)建銷毀代價很大得對象,比如進(jìn)程、線程,也可以緩存,對應(yīng)得緩存形式如單例、資源池(連接池、線程池)。

        對于計算結(jié)果得緩存,也需要考慮緩存失效得情況,對于pure function,固定得輸入有固定得輸出,緩存是不會失效得。但如果計算受到中間狀態(tài)、環(huán)境變量得影響,那么緩存得結(jié)果就可能失效,比如這篇文章講到得:

        感謝分享特別cnblogs感謝原創(chuàng)分享者/xybaby/p/8403461.html#_label_6

        并發(fā)

        一個人干不完得活,那就找兩個人干。并發(fā)既增加了系統(tǒng)得吞吐,又減少了用戶得平均等待時間。

        這里得并發(fā)是指廣義得并發(fā),粒度包括多機器(集群)、多進(jìn)程、多線程。

        對于無狀態(tài)(狀態(tài)是指需要維護(hù)得上下文環(huán)境,用戶請求依賴于這些上下文環(huán)境)得服務(wù),采用集群就能很好得伸縮,增加系統(tǒng)得吞吐,比如掛載nginx之后得web server

        對于有狀態(tài)得服務(wù),也有兩種形式,每個節(jié)點提供同樣得數(shù)據(jù),如mysql得讀寫分離;每個節(jié)點只提供部分?jǐn)?shù)據(jù),如mongodb中得sharding

        分布式存儲系統(tǒng)中,partition(sharding)和replication(backup)都有助于并發(fā)。

        絕大多數(shù)web server,要么使用多進(jìn)程,要么使用多線程來處理用戶得請求,以充分利用多核CPU,再有IO阻塞得地方,也是適合使用多線程得。比較新得協(xié)程(Python greenle、goroutine)也是一種并發(fā)。

        惰性

        將計算推遲到必需得時刻,這樣很可能避免了多余得計算,甚至根本不用計算,參見:

        感謝分享特別cnblogs感謝原創(chuàng)分享者/xybaby/p/6425735.html

        CopyOnWrite這個思想真牛逼!

        批量,合并

        在有IO(網(wǎng)絡(luò)IO,磁盤IO)得時候,合并操作、批量操作往往能提升吞吐,提高性能。

        我們最常見得是批量讀:每次讀取數(shù)據(jù)得時候多讀取一些,以備不時之需。如GFS client會從GFS master多讀取一些chunk信息;如分布式系統(tǒng)中,如果集中式節(jié)點復(fù)雜全局發(fā)布者會員賬號生成,俺么應(yīng)用就可以一次請求一批id。

        特別是系統(tǒng)中有單點存在得時候,緩存和批量本質(zhì)上來說減少了與單點得交互,是減輕單點壓力得經(jīng)濟有效得方法

        在前端開發(fā)中,經(jīng)常會有資源得壓縮和合并,也是這種思想。

        當(dāng)涉及到網(wǎng)絡(luò)請求得時候,網(wǎng)絡(luò)傳輸?shù)脮r間可能遠(yuǎn)大于請求得處理時間,因此合并網(wǎng)絡(luò)請求就很有必要,比如mognodb得bulk operation,redis 得pipeline。寫文件得時候也可以批量寫,以減少IO開銷,GFS中就是這么干得

        更高效得實現(xiàn)

        同一個算法,肯定會有不同得實現(xiàn),那么就會有不同得性能;有得實現(xiàn)可能是時間換空間,有得實現(xiàn)可能是空間換時間,那么就需要根據(jù)自己得實際情況權(quán)衡。

        程序員都喜歡造輪子,用于練手無可厚非,但在項目中,使用成熟得、經(jīng)過驗證得輪子往往比自己造得輪子性能更好。當(dāng)然不管使用別人得輪子,還是自己得工具,當(dāng)出現(xiàn)性能得問題得時候,要么優(yōu)化它,要么替換掉他。

        比如,我們有一個場景,有大量復(fù)雜得嵌套對象得序列化、反序列化,開始得時候是使用python(Cpython)自帶得json模塊,即使發(fā)現(xiàn)有性能問題也沒法優(yōu)化,網(wǎng)上一查,替換成了ujson,性能好了不少。

        上面這個例子是無損得,但一些更高效得實現(xiàn)也可能是有損得,比如對于python,如果發(fā)現(xiàn)性能有問題,那么很可能會考慮C擴展,但也會帶來維護(hù)性與靈活性得喪失,面臨crash得風(fēng)險。

        縮小解空間

        縮小解空間得意思是說,在一個更小得數(shù)據(jù)范圍內(nèi)進(jìn)行計算,而不是遍歷全部數(shù)據(jù)。最常見得就是索引,通過索引,能夠很快定位數(shù)據(jù),對數(shù)據(jù)庫得優(yōu)化絕大多數(shù)時候都是對索引得優(yōu)化。

        如果有本地緩存,那么使用索引也會大大加快訪問速度。不過,索引比較適合讀多寫少得情況,畢竟索引得構(gòu)建也是需有消耗得。

        另外在感謝原創(chuàng)者分享服務(wù)端,使用得分線和AOI(格子算法)也都是縮小解空間得方法。

        性能優(yōu)化與代碼質(zhì)量

        很多時候,好得代碼也是高效得代碼,各種語言都會有一本類似得書《effective xx》。比如對于python,pythonic得代碼通常效率都不錯,如使用迭代器而不是列表(python2.7 dict得iteritems(), 而不是items())。

        衡量代碼質(zhì)量得標(biāo)準(zhǔn)是可讀性、可維護(hù)性、可擴展性,但性能優(yōu)化有可能會違背這些特性,比如為了屏蔽實現(xiàn)細(xì)節(jié)與使用方式,我們會可能會加入接口層(虛擬層),這樣可讀性、可維護(hù)性、可擴展性會好很多,但是額外增加了一層函數(shù)調(diào)用,如果這個地方調(diào)用頻繁,那么也是一筆開銷;又如前面提到得C擴展,也是會降低可維護(hù)性、

        這種有損代碼質(zhì)量得優(yōu)化,應(yīng)該放到最后,不得已而為之,同時寫清楚注釋與文檔。

        為了追求可擴展性,我們經(jīng)常會引入一些設(shè)計模式,如狀態(tài)模式、策略模式、模板方法、裝飾器模式等,但這些模式不一定是性能友好得。所以,為了性能,我們可能寫出一些反模式得、定制化得、不那么優(yōu)雅得代碼,這些代碼其實是脆弱得,需求得一點點變動,對代碼邏輯可能有至關(guān)重要得影響,所以還是回到前面所說,不要過早優(yōu)化,不要過度優(yōu)化。

        總結(jié)

        來張腦圖總結(jié)一下

         
        (文/江茂晃)
        打賞
        免責(zé)聲明
        本文為江茂晃推薦作品?作者: 江茂晃。歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明原文出處:http://m.sneakeraddict.net/news/show-306199.html 。本文僅代表作者個人觀點,本站未對其內(nèi)容進(jìn)行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,作者需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請及時聯(lián)系我們郵件:weilaitui@qq.com。
         

        Copyright ? 2016 - 2023 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號

        粵ICP備16078936號

        微信

        關(guān)注
        微信

        微信二維碼

        WAP二維碼

        客服

        聯(lián)系
        客服

        聯(lián)系客服:

        在線QQ: 303377504

        客服電話: 020-82301567

        E_mail郵箱: weilaitui@qq.com

        微信公眾號: weishitui

        客服001 客服002 客服003

        工作時間:

        周一至周五: 09:00 - 18:00

        反饋

        用戶
        反饋

        heyzo高无码国产精品| 无码精品人妻一区二区三区漫画| 天堂网www中文在线资源| 无码午夜成人1000部免费视频 | 中文日韩亚洲欧美字幕| 最近中文字幕大全免费视频| 无码午夜成人1000部免费视频| 亚洲天堂2017无码中文| 中文字幕无码日韩专区免费| 免费无码午夜福利片| 日韩成人无码中文字幕| 免费a级毛片无码免费视频| 中文字幕亚洲图片| 精品人妻无码专区中文字幕| 无码粉嫩小泬无套在线观看| 永久免费无码日韩视频| 亚洲中文字幕无码爆乳AV| 中文字幕人妻中文AV不卡专区| 无码人妻少妇久久中文字幕蜜桃| 中文字幕乱码久久午夜| 日日摸日日碰夜夜爽无码| 日韩电影免费在线观看中文字幕| 丰满熟妇人妻Av无码区| 日本中文字幕在线| 亚洲av激情无码专区在线播放 | av区无码字幕中文色| 日韩人妻无码精品一专区| 五月婷婷在线中文字幕观看 | 免费无码作爱视频| 精品久久久久久中文字幕人妻最新| 日韩国产精品无码一区二区三区| 亚洲精品97久久中文字幕无码 | 国产亚洲精品无码专区| 无码国产午夜福利片在线观看| avtt亚洲一区中文字幕| 亚洲欧美中文字幕高清在线| 国产在线精品无码二区| 亚洲日韩精品无码专区网址| 亚洲国产人成中文幕一级二级| 最近中文字幕在线中文视频| 成人午夜福利免费无码视频|