也許硬體廠商會希望軟體效能不佳,誘使人們採購更高價位的硬體,但沒有程式人希望自己所開發的軟體系統效能低落。因此,如何開發高效的系統,一直是軟體設計領域中,十分重要的一環。
影響效能的因素錯綜複雜
系統的運作效能,通常是多個不同因素交互影響著,例如:是否發揮硬體特性、系統架構、程式語言的效率、編譯器的好壞、程式庫的效率、演算法的優劣、程式碼寫作的良窳、效能最佳化的技巧、系統參數設定等。
對於一個需要大量多媒體運算的系統,倘若能夠善用硬體提供的多媒體運算機制,相較於純粹以軟體方式實作這些運算功能,在效能上肯定會有很大的差異。使用群集(Cluster)伺服器分散計算量,達到負載平衡的系統架構,相較於單一伺服器,也能提供更強的系統效能。
而使用高效的程式語言、搭配高效的程式庫,輔以高效的編譯器,自然能產出效能較佳的執行碼。不同的演算法解決同一個計算問題,所需的運算時間、空間,也有可能導致天差地遠的分別。
時間複雜度相同的演算法,而讓優秀的程式人所寫出的程式碼,實際執行時間很有機會低於普通程式人所撰寫的程式碼。此外,如果能妥善運用Resource Pooling與Caching的系統,效率也會大幅勝過沒有使用這些機制的系統。此外,諸如Connection Pool之類系統參數的調校是否合宜,也對系統效能有深遠的影響。
面對效能的第一個抉擇──訂定目標
影響系統效能的因素如此繁多,在規畫與設計系統時,對於效能的態度又應該是如何呢?
人們在處理效能議題,面對的第一個抉擇,往往是必須決定需要多少效能,也就是決定效能目標。
不可諱言的,效能的追求,隨著效能調校之後的提升,邊際效應會逐漸遞減。這意謂著,到了效能調校的後期,花費更多的力氣,也只能得到些許提升,但所得到的效能真的是我們實際需要的嗎?
在決定系統的效能目標時,不能抱持著那種「系統要盡可能快」的態度。設定這種目標,等於沒有設定目標。你要做的,便是明定數量,諸如:同時允許上線人數要多少、每天要能服務幾名訪客、承接多少Page View、處理多少個服務請求之類具體目標。有了具體的目標,日後的設計、實作、以及效能最佳化等工作,才有可以依循的準則。
效能與彈性之間,兩邊在拔河
效能和系統設計中的一些因子是相互衝突的。魚與熊掌不可得兼,希望提高效能,有時就免不了得犧牲某些系統的特性,我們最常面對的,便是在效能及彈性之間取捨。
設計者做了過多的考量及設計,以增加系統的彈性。而我們雖然會在規畫系統之初,先制定預期的系統效能目標,但是實務上,並不容易在未開發完成時,就很準確地評量系統能否滿足這個目標。設立目標最大的作用,還是在開發後期,做為效能調校努力的基準。
所以在效能和彈性之間,我們應該以系統可預見需要的彈性做為先天限制,在開發過程中的各項決策,以彈性為較優先的考量,只要留意自己是否逾越了過度工程化的界限,同時避開重大的效能陷阱,就不致於犯下太嚴重的過錯。
在先天條件的限制下,仍可找到努力的空間
在專案之初,開發團隊就必須訂定許多和效能相關的決策。本文一開始提到許多影響系統效能的因素,其中有些因素,是專案先天的限制,並不容易改變,也沒什麼選擇的空間,例如程式語言。
專案開發所採用的程式語言,有時是客戶的選擇,有時是開發團隊成員屬性所左右,因此在專案之初就決定了。程式語言和開發的生產力息息相關。使用適宜的程式語言,有可能大幅增加生產力,而時間及投入的人力成本,正是開發最為關鍵的限制。
因此,基於許多各種不同的原因,先決定了要使用的程式語言。既定的程式語言,對效能已經有一個既定的框架存在,開發者只能在這個框架下努力,例如:選擇效率高的程式庫、或是編譯器、甚至是執行環境,力求好的表現。
同樣是Java程式語言,JDK 1.6的JVM效能,就勝過之前的版本。即便在已選擇程式語言的情況下,仍有許多和效能有關的決策必須處理。
演算法的好壞,效能影響差很多
當開發的時程進入實作階段,最常發生的效能問題,是運用不好的演算法。解決同一個問題,不同時間複雜度的演算法之間,隨著問題的規模越大,需要耗費的時間會相差越多。
我們時常在許多開發專案中看到使用相當原始(或稱拙劣)的演算法解決問題。程式人在開發之際,往往不會太在意所用的演算法究竟好或不好。程式人往往只在乎能不能在期限內,盡快達成任務,所以很容易在壓力之下屈服,選擇易於實作的演算法。或者是根本不知道有更好的演算法,而使用效率不高的演算法。
演算法的效能不好,在系統開發時或測試初期,由於規模小,不容易被察覺。在這種情況下,就有可能在系統埋下許多不為人知的效能「地雷」,這些地雷會一直等到系統開始大規模測試,甚至是正式釋出、上線時,才會被引爆。
撰寫不佳的程式碼,也是類似的情況。程式人可能基於本身的素質、也許基於習慣問題、也有可能是因為時程緊迫的壓力,寫下了效能表現不佳的程式碼。
然而開發團隊的成員素質不齊是常有的事,很難要求團隊的成員素質既高又整齊,所以必須接受這個現實。
程式碼審閱可掃出顯而易見的效能「地雷」
為了避免程式人使用不佳的演算法,開發團隊中扮演架構師角色的成員,可以在細部設計時,指定所使用的演算法,並提供程式人相關的參考資訊。但,為了提早找出效能不佳的程式碼或實作,只能利用程式碼審閱(Code Review)的機會,掃出潛藏在程式碼中的地雷。
開發階段的程式碼審閱,可以經由具豐富經驗的程式員,以人工的方式,找出隱藏在程式碼中的效能地雷。不過,這種做法,只能適用在顯而易見的效能地雷。這類有問題的程式碼,多半在寫法上有明顯的缺點,所以不需要任何效能上的量測,便能夠輕易識別。
但是,有許多效能的問題,並不那麼顯而易見。這時候,就會需要效能量測的工具(Profiler)協助分析系統的執行。
在系統功能開發到達一個段落後,便會進入測試階段。測試初期,多會著重在功能面的正確性,但是到了測試階段的後期或系統正式釋出或上線時,由於功能面的缺失已經修正得差不多,關注的焦點便會從功能性上的臭蟲,移轉至效能面的表現(也就是說,當使用者或客戶開始抱怨你的系統不夠快時,便代表你的系統在功能實作面上,已經趨於穩定了)。
這個時候,開發團隊會需要開始調校效能或最佳化的動作,使得效能可以滿足專案啟始之初所制定的目標。
《作者簡介》王建興
清華大學資訊工程系的博士研究生,研究興趣包括電腦網路、點對點網路、分散式網路管理、以及行動式代理人,專長則是Internet應用系統的開發。曾參與過的開發專案性質十分廣泛而且不同,從ERP、PC Game到P2P網路電話都在他的涉獵範圍之內。
相關閱讀:
高效的系統開發要領(2)找出最關鍵的效能瓶頸
高效的系統開發要領(3)當瓶頸在運算量時,先從程式下手
高效的系統開發要領(4)當瓶頸在檔案存取時,善用快取
高效的系統開發要領(5)努力瘦身,輕鬆通過對外頻寬的瓶頸
高效的系統開發要領(6)伺服器運用頁面快取,加速效果驚人
高效的系統開發要領(7)把關資料處理細節,效能過關很簡單
熱門新聞
2025-12-12
2025-12-12
2025-12-15
2025-12-12
2025-12-12
2025-12-12