轉寄︰程式碼該怎麼改,才能提升性能? - J.W AnyTHing - udn部落格

2011/3/10 - 例如購物網站在訂單付款時的信用卡授權機制,就可以以此方式來設計,而不因銀行端授權系統回應時間過長,造成訂單交易因逾時而失敗,或是因 ...
程式碼該怎麼改,才能提升性能?
文/陳宏一 2011-03-09
    
網站效能分析操作心法 第5回 應用伺服器的效能問題中,來自應用程式本身所引起的比例很高,程式的寫法固然有千百種,但我們仍能找到耗費較少系統資源的方法而達到一樣的結果

曾在某知名電信業者的正式環境上,看到一支兩千多行的ASP程式,問當時的負責人為何不以較彈性的方式改寫,他回應我,這支程式歷史悠久、檔案不完整,沒人敢改,只求功能正常運行,那敢談論效能要改善到多好?

工欲善其事,必先利其器
要求每個程式開發人員都具備良好的程式撰寫品質,實務上除了建立良好觀念及落實程式撰寫規範外,在開發流程若搭配檢測工具進行品質及效能的把關,像是 Findbugs、Apache PMD等,至少可以將程式品質維持在一定的水準。此類工具能掃描網站程式,發現可能造成的效能問題的程式碼。
應用伺服器上的VM對於程式開發人員而言,它總像個神秘的潘朵拉寶盒,未透過一些工具來揭開它的面紗,難以有效掌握黑箱裡頭的運行狀況。而網站執行階段若能進一步採用像是Quest JProbe、Foglight、JProfiler等效能分析工具,當發生效能問題時,可直接觀察當下系統資源的使用狀況,即時抓出效能問題的原因,直接改寫出問題的程式碼。

然而要從程式面下手改善,也得先從效能問題的癥狀來決定可能的處理方式。常見的系統現象有幾種︰記憶體使用量居高不下,空間無法有效釋放;或是CPU用量持續處於高峰,造成回應速度過慢;以及資料存取方式不當,造成回應時間過長。

避免執行時期需要較高的記憶體用量
程式執行過程中許多變數的宣告使用,都會佔用記憶體一部分空間,包括新建的物件、開啟的檔案、建立的資料庫連線及查詢取得的資料內容等。而網站系統每個訪客連線進來,應用伺服器都會產生一項執行緒,針對這個訪客所瀏覽網頁的請求,個別提供服務。

例如不少網頁程式設計,會使用Session變數當成是網頁之間資料傳遞的方式,常見的像是會員登入與否的驗證,登入後的個人化資料等。大量使用 Session變數,而且物件化的設計,更容易造成儲存過量的資料在記憶體中,所佔用的空間便十分可觀,此狀況在網站流量暴增時,就容易造成實體記憶體空間不足,而轉以虛擬記憶體的機制來切換(Swap)時,運作過程所花費的I/O時間,成為效能不佳的關鍵點。

以其他方式來取代Session變數的過度耗用,節省網站系統在執行時期所需配置的記憶體空間。像是搭配Cookie變數輔助儲存,利用FORM HIDDEN變數來協助傳遞,或是利用URL rewriting的方式,都是可考慮的替代方案。不過需同步考量這些資料的敏感性,搭配適度的加解密機制,以防資料外洩或傳遞過程中被竄改。

就VM的Garbage Collection(GC)機制而言,一旦所宣告的物件及變數不再使用,就會回收,在適當時機進行GC作業釋放所佔用的系統資源,主要是Heap Memory記憶體區域。然而不當的程式撰寫方式會造成Memory Leak,即物件不再使用也無法被回收,造成記憶體無法釋放。此類問題比較難捉摸,需要情境模擬及去除其他干擾因子來逐步找出,或透過效能檢測工具來找出根本原因。

而變數宣告的時機點,物件之間依存性的複雜程式,也影響記憶體空間使用。這涉及到變數佔用記憶體的時間長短,在程式撰寫時,要善用Try-catch-finally的區段,將不再使用的變數null化,養成隨手做環保的好習慣。

造成高CPU用量,系統回應時間較長的原因
當你的網站系統是屬性CPU bound的服務居多(像是相簿服務的圖片格式壓縮功能),從效能檢測工具可以觀察得知,哪一個元件、方法花費最多執行時間。能採取的策略是優化你的演算法,以及將程式碼改寫得更有效率。程式邏輯演算法所付出的成本,當然你可以利用傳統Big O的複雜度評估方式來計算,或者是透過效能檢測工具來發掘,抓出執行時間較長且被叫用較多次數的物件方法,評斷其合理與否,以及是否仍有改善的空間。

程式常會因為不斷新增功能,而使得原本程式邏輯未能以整理觀點,來考量處理方式是否合理。像是方法是否被重複呼叫,運算過程中是否有重複宣告相同意義的多餘變數,或是否以合適的物件結構來儲存運算中所需的資料。這些都造成運算成本浪費。因此定時對程式碼審視重構是必要的,適當地重整邏輯結構,能讓程式碼執行更有效率。

導入設計模式同時強化結構及效能
在程式設計的領域中,設計模式(Design Pattern)的觀念累積了先人解決系統設計的最佳實踐方案,維持著物件導向設計高內聚力、低耦合性的本質,不僅建立良好的系統軟體架構,同時保有系統彈性及擴充性,亦能解決效能上的問題。

例如,網站系統中最常見使用的MVC模式,出現在多項知名的軟體框架中,更是適用在網站架構特性;而早期採用EJB技術時,也利用Value Object來處理資料存取的問題,減少網路傳輸時間(Latency Time);利用Factory或Builder模式,來建立特定需要的物件,以滿足物件重複使用(reuse)的精神;利用Iterator模式,來處理網頁內容分頁的機制,可大幅縮短巨量資料查詢時的回應時間;利用Service Facade模式,提供一致化之服務介面,該服務物件則可被重複叫用,並結合Singleton模式來發揮快取效果,提升執行效率。

有效提升資料存取及外部系統整合
許多網站在開發設計時,往往將大多數的資料以資料庫方式來儲存,當網站流量升高時,對資料庫系統的衝擊亦相當可觀。故在資料模型的設計時,若能不以資料庫方式儲存,就盡可能改以檔案或記憶體方式,在效能表現上也遠優於資料庫。像是一些高流量的網站,大都以檔案方式儲存內容(像是商品說明、促銷活動內容等),少數異動較為頻繁的資料(像是商品售價、庫存量等),才放到資料庫。

若網站需要整合其他第三方系統,外部系統本身的效能表現亦直接反應在網頁回應速度上。此時,在設計上利用非同步訊息(Asynchronized Message)方式整合,可大幅縮減整體回應時間,而且亦能提供異質系統之間進行資料交換的可信度。例如購物網站在訂單付款時的信用卡授權機制,就可以以此方式來設計,而不因銀行端授權系統回應時間過長,造成訂單交易因逾時而失敗,或是因回應時間過長引起使用者關閉視窗,造成訂單資料異常。

動態網頁程式幾乎跟資料庫脫離不了關係,所以資料存取方式的合適度,也直接影響效能優劣。在撰寫資料存取程式時,多以Prepared Statement方式來善用Query Cache的特性,若是採用Persistence Framework來進行資料存取,Framework本身提供的Cache也提升存取效能;而DAO設計模式的引用,可同時結合Connection Pool、Object Cache及Query Cache的效果,明顯改善資料存取效能。

若程式是使用SQL命令對資料庫進行操作,SQL命令本身亦需要優化調整,必須結合資料表的索引鍵值進行條件查詢。若查詢時,需要透過跨多個資料表進行 table join的查詢時,資料表本身的資料筆數必須要考慮進來,因為這會影響到資料比對的數量,以及所需耗費的時間。

資料來源︰IThome

相關標籤:回應時間過長
http://blog.udn.com/lazybone1981/4965575
轉寄︰程式碼該怎麼改,才能提升性能? - J.W AnyTHing - udn部落格 相關新聞列表
請輸入關鍵字:
聯絡我們 - 免責聲明 - 問題反饋 - 廣告合作   

Copyright © 2013 tnscg.COM All Rights Reserved