軟體的效能設計(二) 臨時物件對軟體效能的影響 (轉)
的設計(二) 臨時對軟體效能的影響
劉彥清·yesky
臨時物件的存在時間一般都比較短暫,除了作為其他資料的容器外,沒有其他什麼用途,開發人員一般用它向方法傳遞資料或從方法中返回資料。文章的第一部分探討了建立臨時物件是如何影響效能的,並表明恰當的類的介面設計可以有效地減少臨時物件的建立。透過避免設計這樣的介面,就可以減少臨時物件的建立,降低對程式效能的影響程度。在本篇文章中,我將討論過多地建立臨時物件的問題並在後面的文章中提供一些成熟的技術來避免過多地建立臨時物件。
僅僅對String說NO?
說到建立臨時物件,String類是最大的"罪魁禍手"。為了說明這一點,我在這篇文章的第一部分中開發了一個匹配類的例子,並演示了一個看起來頗為正常的介面是如何因為建立了臨時物件而比一個具有較好介面的類似的類執行速度慢數倍的。下面是最初的和效能較好的類的介面:
BadRegExpMatcher
public class BadRegExpMatcher {
public BadRegExpMatcher(String regExp);
/** 把輸入文字與特定的表示式進行匹配,如果匹配則返回匹配的文字,否則返回空字元 */
public String match(String inputText);
}
BetterRegExpMatcher
class BetterRegExpMatcher {
public BetterRegExpMatcher(...);
/** 向匹配子程式提供多種格式的輸入━━String、字元陣列和字元陣列的子集。如果不匹配則返回-1,如果匹配,則返回匹配開始處的偏移量 */
public int match(String inputText);
public int match(char[] inputText);
public int match(char[] inputText, int offset, int length);
/** 如果匹配,則返回匹配的長度,程式可以從返回的匹配開始處偏移量和長度重新構造匹配的文字 */
public int getMatchLength();
/** 如果呼叫程式需要,這個例程可以很方便地構造出匹配字串 */
public String getMatchText();
}
大量使用BadRegExpMatcher的程式要比使用BetterRegExpMatcher的程式執行速度慢一些。第一,呼叫程式必須建立String物件向match()傳遞引數,match()也必須建立一個String物件向呼叫程式返回匹配的文字。每次呼叫時都會建立二個物件,這聽起來也許沒有什麼大問題,但如果頻繁地呼叫match(),建立這二個物件對效能產生的影響就大了。使用BadRegExpMatcher的程式的效能問題並不源於其編碼而源於其介面,象這樣設計的介面,臨時物件的建立是不可避免的。
BetterRegExpMatcher用比較簡單的資料型別(整型、字元陣列)取代了在match()中使用的String物件,從而無需在呼叫程式和match()之間透過中間物件傳遞資料。
由於在設計階段比在完成整個程式後再進行修改能夠更好地避免程式效能方面的問題,因此應該在類的介面如何處理物件的建立這個問題上多花些時間。在RegExpMatcher中,其方法要求輸入和返回String物件就可能對效能有潛在的影響,因為String類的物件是不可變的,因此對String類物件引數進行處理就會要求在每次呼叫時建立一個新的String物件。
由於不可變性通常與額外的物件建立聯絡在一起━━這大部分原因都要"歸功"於其不可變性,許多人員就斷定不可變的物件一定會影響程式的效能。其實真實的情況要複雜得多,實際上,不可變性有時還能夠提升程式的效能,可變的物件也能夠引起程式效能的下降,可變性對程式效能的影響取決於其使用方式。
程式會經常對文字字串進行操作和修改━━不可改變性確實是一個麻煩。在每次對String進行操作時━━例如查詢或選擇一個字首或子串,把它轉換為大寫或小寫,或者將二個字串合併成一個新的字串時,就必須建立一個新的String類物件。
另一方面,我們可以自由地共享一個不可變物件的地址而無需擔心物件會被改變,此時,不可變物件在效能上就比可變物件要好許多。
可變物件也存在臨時物件問題
在RegExpMatcher中,當一個方法返回的資料型別為String類時,就有必要建立一個新的String類物件。在BadRegExpMatcher中存在的問題之一是match()返回的是一個物件而不是一個簡單型別的資料━━因為一個方法返回一個物件,並不意味著一定會建立一個新的物件。考慮一下Point和Rectangle等.awt中的幾何類,一個Rectangle只不過是由四個整數━━左上角點的X、Y座標以及寬度和高度組成的,AWT類了元件的位置並透過getBounds()方法將它作為一個Rectangle類物件返回:
public class Component {
...
public Rectangle getBounds();
}
在上面的例子中,getBounds()方法僅僅起一個輔助性作用,它只是宣告一些元件內部的有關資訊。getBounds()真的必須建立它返回的Rectangle物件嗎?也許是這樣的吧,我們來看一下getBounds()的編碼:
public class Component {
...
protected Rectangle myBounds;
public Rectangle getBounds() { return myBounds; }
}
當有程式呼叫上面例子中的getBounds()時,並不會建立新的物件,因為元件已經知道它的位置,因此getBounds()是比較高效的。然而,Rectangle的可變性還引起了其他問題,當一個呼叫它的程式下面的程式碼時會出現什麼樣的情況呢?
Rectangle r = component.getBounds();
...
r.height *= 2;
因為Rectangle具有可變性,上面的程式碼將引起元件的改變,對於象AWT這樣的GUI工具包而言,這將是災難性的,因為當一個元件變化時,需要重新重新整理螢幕,同時還需要通知事件監視程式。因此上面的Component.getBounds()的執行是相當危險的,下面所示的方式才是比較的:
public Rectangle getBounds() {
return new Rectangle(myBounds.x, myBounds.y,
myBounds.height, myBounds.width);
}
但是,就象RegExpMatcher那樣,每次呼叫getBounds()都會建立一個新的物件,下面的程式碼將會建立四個臨時物件:
int x = component.getBounds().x;
int y = component.getBounds().y;
int h = component.getBounds().height;
int w = component.getBounds().width;
對於String類而言,建立物件是必要的,因為String是不可變的。但是在這個例子中,建立臨時物件似乎也是必需的,因為Rectangle具有可變性,我們可以透過不在介面中使用任何物件來避免象String引起的那樣的問題。儘管在與RegExpMatcher類似的場合中,這一方案並非總是可行的或理想的,然而,幸運的是,在設計類時可以採用一些技術,既能使用小一些的物件又不會遇到使用太多的小物件所引起的問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989518/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 軟體的效能設計(一)介面設計對軟體效能的影響 (轉)
- 軟體效能的設計(三)資料型別對軟體效能的影響 (轉)資料型別
- 軟體測試對軟體質量的影響有那些?
- JavaScript 事件對記憶體和效能的影響JavaScript事件記憶體
- 硬體環境對系統效能的影響
- 影響MySQL效能的硬體因素MySql
- 影響MySQL效能的硬體因MySql
- 軟體測試對軟體質量有哪些影響?
- 軟體教練說:效能優化與效能設計,“相親相愛”的一對優化
- 人工智慧對軟體測試的影響人工智慧
- 軟體設計雜談(二)--軟體設計與設計人員的個人素質 (轉)
- 新會計準則實施對財務軟體的影響
- 伺服器核心硬體的效能如何影響伺服器的整體效能?伺服器
- 軟體中的效能指標指標
- 【太陽軟體】動態換ip軟體:反爬蟲對抗對資料分析的影響爬蟲
- Arraysize的設定以及對查詢效能的影響
- 【軟體工程】物件導向的設計軟體工程物件
- 軟體效能測試
- 勒索軟體攻擊影響
- 軟體效能測試的優勢
- 低程式碼開發對軟體開發流程的影響
- 利用Windows效能計數器分析軟體產品的效能瓶頸Windows
- 軟體效能測試有哪些效能指標?可做效能測試的軟體檢測機構安利指標
- JAVA 異常對於效能的影響Java
- 【軟體工程】軟體設計之總體設計軟體工程
- DB2 HADR對效能的影響DB2
- InnoDB 隔離模式對 MySQL 效能的影響模式MySql
- 轉:RAID的概念及RAID對於SQL效能的影響AISQL
- 軟體設計技巧:產品規劃會影響並應指導你的設計 - james
- 大型網站的 HTTPS 實踐(二):HTTPS 對效能的影響網站HTTP
- 大型網站的 HTTPS 實踐(二)——HTTPS 對效能的影響網站HTTP
- WebSphere效能監控軟體WASMonWebASM
- 面對物件是一種軟體設計思想,和具體的實現無關物件
- 軟體效能測試的幾個階段
- 軟體效能測試的內容有那些?
- 淺談軟體效能提升相關的概念
- Sort_Buffer_Size 設定對伺服器效能的影響伺服器
- 軟體工程——程式導向的軟體設計方法軟體工程