性能優化的七大殺手锏!
性能優化可分為業務優化和技術優化兩類。業務優化雖能帶來顯著效果,但主要屬于產品和管理范疇。作為程序員,日常工作中的優化多依靠技術手段達成既定的優化目標。以下為大家詳細介紹7種常見的技術優化手段。
圖片
代碼復用優化
在編寫代碼時,我們常常會發現許多重復代碼。將這些代碼提取出來,封裝成公共方法,下次使用時就無需重新編寫,這就是復用思想在編碼邏輯上的體現。在數據存取方面,同樣存在復用情況。
在軟件系統里,數據復用常涉及緩沖和緩存。需注意,這兩個概念有本質區別。
- 緩沖(Buffer):常用于數據的暫存,然后進行批量傳輸或寫入,多采用順序方式,旨在緩解不同設備間頻繁、緩慢的隨機寫操作,主要針對寫操作。
- 緩存(Cache):對已讀取數據的復用,通過將數據存儲在高速區域,以加快后續讀取速度,主要針對讀操作。
此外,對象池化操作也是復用的一種形式,如數據庫連接池、線程池等,在Java中應用廣泛。由于這些對象的創建和銷毀成本較高,使用后將其暫時存儲,下次使用時無需進行耗時的初始化操作。
計算性能優化
并行執行
如今,大多數硬件采用多核CPU。為加快任務執行速度,并行執行是最優選擇。并行執行主要有以下三種模式:
- 多機并行:通過負載均衡,將流量或大型計算任務拆分為多個部分,同時進行處理。例如,Hadoop利用MapReduce將任務分散到多臺機器上并行計算。大流量系統通過負載均衡器將流量分擔到后端服務的多個節點上執行。
- 多進程并行:以Nginx為例,采用NIO編程模型,Master統一管理Worker進程,由Worker進程負責請求代理,充分利用硬件的多個CPU。
- 多線程并行:這是Java程序員常用的方式。如Netty采用Reactor編程模型,基于線程實現。Boss線程接收請求,然后調度給Worker線程進行業務計算。此外,Golang的協程比線程更輕量級,本質上也是利用多核實現任務并行執行。
同步轉異步
將同步操作改為異步操作,通常需要改變編程模型。同步請求會一直阻塞,直到返回成功或失敗結果。雖然編程模型簡單,但在應對突發、時間段傾斜的流量時,容易導致請求失敗。而異步操作支持橫向擴容,能緩解瞬時壓力,使請求更加平滑。
惰性加載
利用常見的設計模式,如單例模式、代理模式等,可以優化業務并提升用戶體驗。例如,在進行UI編程時,若要顯示大量圖片,可先加載占位符,再通過后臺線程逐步加載所需資源,避免窗口僵死。
結果集優化
以XML和JSON為例,JSON不僅書寫簡單,而且體積更小,傳輸和解析效率更高。Google的Protobuf體積更小,雖可讀性降低,但在高并發場景(如RPC)中能顯著提高效率,這是結果集優化的典型案例。
在C/S模式的Web服務中,數據從服務器傳輸到客戶端需要分發多份,減少數據存儲量能顯著提升傳輸性能并降低成本。例如,Nginx通常會開啟GZIP壓縮,使傳輸內容更加緊湊,客戶端只需少量計算能力即可解壓。
結果集優化的一般思路是保持返回數據的精簡,去除客戶端不需要的字段。對于時效性要求不高但處理能力要求高的業務,可采用批量處理方式,減少網絡連接交互。此外,對數據集合進行處理優化,如使用索引或Bitmap位圖,可加快數據訪問速度。
資源沖突優化
開發中會涉及多種共享資源,包括單機資源(如HashMap)、外部存儲(如數據庫行)、單個資源(如Redis的Setnx)以及多個資源的協調(如事務、分布式事務)。性能問題與鎖密切相關,如數據庫的行鎖、表鎖,Java中的各種鎖,以及底層的CPU命令級鎖、JVM指令級鎖和操作系統內部鎖等。
并發會導致資源沖突,解決方法是加鎖。事務本質上也是一種鎖。鎖可分為樂觀鎖和悲觀鎖,樂觀鎖效率更高;還可分為公平鎖和非公平鎖,在任務調度上略有差異。對無鎖隊列的研究也能顯著提升性能。
算法優化
算法能顯著提升復雜業務的性能,實際業務中常使用算法的變種。在CPU緊張的業務中,為加快處理速度,常采用空間換時間的策略。
算法優化屬于代碼調優,需要熟悉所使用語言的API,靈活運用算法和數據結構。常見的降低時間復雜度的方法有遞歸、二分、排序、動態規劃等。不同的實現方式對系統性能影響巨大,如LinkedList和ArrayList在隨機訪問性能上差異明顯,CopyOnWriteList在讀多寫少場景下能降低鎖沖突。
高效實現
編程時應盡量使用設計理念良好、性能優越的組件。例如,有了Netty就不應再選擇較老的Mina組件;設計系統時,應避免使用SOAP這種耗時的協議;使用JavaCC等語法分析器比正則表達式效率更高。
若通過測試分析找到系統瓶頸,應使用更高效的組件替換關鍵組件。適配器模式在這種情況下非常重要,許多公司會在現有組件上進行抽象封裝,以便在底層組件切換時,上層應用不受影響。
JVM優化
Java程序運行在JVM虛擬機上,其性能受JVM制約。合理優化JVM參數能提升Java程序性能,參數配置不當可能導致OOM等嚴重問題。
目前,G1垃圾回收器應用廣泛,通過少量參數配置即可實現高效內存回收。CMS垃圾回收器已在Java 14中被移除,因其GC時間不可控,應盡量避免使用。
JVM性能調優需綜合考慮各方面因素,了解JVM內部運行原理有助于深入理解代碼,編寫更高效的程序。
總結
今天為大家從代碼復用、計算性能、結果集優化、資源沖突優化、算法優化、高效實現和JVM優化等方面介紹了性能優化的可行方案和注意事項。希望小伙伴們能夠從中學到對自己有用的知識。