文章來自微信公眾號:techreading 技術閱讀Martin Thompson 在巴西圣保羅的InfoQ全球軟件開發大會上,分享了在軟件開發中,哪些問題容易影響系統的性能。他總結了在工作中比較常見的10個問題以及相應的解決辦法
文章來自微信公眾號:techreading 技術閱讀
Martin Thompson 在巴西圣保羅的InfoQ全球軟件開發大會上,分享了在軟件開發中,哪些問題容易影響系統的性能。
他總結了在工作中比較常見的10個問題以及相應的解決辦法。
10 環境沒有升級到最新版
很多人不愿意把軟件運行的環境或者系統升級到最新版,因為這些升級很可能會影響到正在運行的軟件或服務。如果你的確希望提高系統的性能,不妨先在測試環境中試一試。
同時,應該采取持續集成的工作流程,經常更新代碼,寫完整的測試,另外試試看是否有一些bug可以通過升級它所依賴的環境就得到解決。
9 重復運行的代碼
這個問題還比較常見。代碼可以運行,和可以有效率地運行是兩回事。一段代碼可能被重復調用了很多次,而表面上看起來卻沒有問題。比如每次需要一個文件就從磁盤讀取,用過之后并不緩存起來,導致接下來訪問這個文件都很慢。
Thompson提到一個案例。在這個案例中,網頁的響應速度非常慢。一般來說是數據庫出了問題。但當他仔細檢查代碼時,卻發現在同一個循環中,數據庫被調用了7000次。問題不是數據庫引起的,而是代碼引起的。
這個案例帶來的教訓就是,永遠要弄清楚你的代碼正在處理什么問題。重復運行的代碼極有可能不會帶來明顯的bug,但并不意味著它沒有問題。
8 數據結構的選擇
當你把超過1GB的數據存在一個數據結構里,就需要小心內存的讀取速度了。對于一個超過2GB的字典,Java的HashMap比.NET的字典慢10倍以上。當然,在別的情況下,Java可能也比.NET快。
處理特別占有內存的數據時,在選擇數據結構上需要仔細斟酌,同時不要太依賴系統自帶的數據結構。
7 內存回收慢
這個問題和上個問題有點兒像,它指是自動內存回收導致的問題。
使用自動內存回收的語言或者工具時,一次性分配過多的內存會增加內存回收的時間,導致系統速度變慢。
6 并行問題
并行任務的通信和同步需要系統開銷,并且這些通信和同步本身并不一定是并行的。根據阿姆德爾定律(Amdahl Law),如果5%的系統活動需要串行,不論使用多少個處理器,系統最多也只能加速20倍。而通用擴展性定律(USL)則指出,在處理器達到一定數量后,并行系統的通訊開銷會導致性能下降。
建立并行系統時,盡量避免引入共享可變的全局數據,因為一旦出了問題,你幾乎不可能知道是哪里的代碼有問題。推薦使用不共享數據的方式構建并行系統,或者嚴格控制寫入數據的場景。
如果需要給算法加速,應首先考慮單線程的情況,再考慮復雜的并行情況。
5 不理解TCP原理
很多人不理解TCP的原理就開始考慮微服務架構,在某些情況下,遇到ACK延時可能導致每秒只能傳輸2-5個包。造成這個現象的原因是,TCP中的Nagle和TCP延時確認兩種算法有時會造成進程死鎖,影響微服務間的通訊。
Thompson推薦通過TCP_NODELAY來禁用Nagle算法,不再限制小包的發送,這樣做的話每秒可多處理5-500個請求。
4 通信同步問題
做過網頁前端的同學對這個問題應該比較了解。瀏覽器訪問網頁時,速度可能會很慢,而再好再貴的服務器也解決不了這個問題,因為用戶還是有可能用2G的手機網絡來訪問你的網站。
但是還是有一些辦法可以盡量讓網頁加載速度快一點。比如優化圖片的大小,讓不同分辨率的屏幕加載不同大小的圖片,優化腳本加載順序,以及盡量采用異步加載等等。
3 數據編碼問題
有些程序員喜歡用JSON,XML,或Base64等編碼格式來傳送數據,因為這樣數據更具有可讀性,在debug的時候非常方便。
但是,系統間的交互是不需要可讀性的。將二進制的數據轉換成文本再轉換成二進制不僅消耗CPU,還消耗網絡帶寬。
其實,你可以用Wireshark來debug服務器通信,或者使用ProtoBuffer,Thrift等工具庫來優化通信過程。
2 函數設計問題
在保證代碼的易讀性的同時,再提高代碼的性能可能會比較困難。但你總得做出取舍,或者多花點時間來好好設計。
有很多技巧可以在避免一些常見性能問題的同時,不會過多犧牲代碼的可讀性。比如,用C++語言寫函數參數時,可以考慮使用引用或指針類型,這樣可以避免在函數內生成臨時的數據結構,而且不用返回數據。對于大部分語言來說,函數返回Iterable就比直接返回Array要好,而且不影響易讀性。
1 日志問題
很驚訝吧,No. 1性能問題竟然是日志帶來的問題!對于大多數日志系統來說,隨著進程數量的增加,記錄日志所需要的時間也會線性增加。在進程數量達到8個時,日志記錄時間大約為0.15s,非常影響系統的響應速度。所以說,日志是一個比較重要的性能瓶頸,而且常常被人忽視。
為了解決這個問題,我們可以使用異步logger,同時小心設計logger所記錄數據的結構,以便進行后續的讀取和處理。
另外,logger重復記錄同一個錯誤是非常浪費性能的,我們可以將它設置為只記錄第一次錯誤,然后設置一個計數器來記錄錯誤發生的次數。
語音:Mia
原作者:Abel Avram@InfoQ
聲明:本文內容來源自網絡,文字、圖片等素材版權屬于原作者,平臺轉載素材出于傳遞更多信息,文章內容僅供參考與學習,切勿作為商業目的使用。如果侵害了您的合法權益,請您及時與我們聯系,我們會在第一時間進行處理!我們尊重版權,也致力于保護版權,站搜網感謝您的分享!