Practicle Java筆記 實踐28-45

 

實踐28

將精力集中於建立良好可靠的設計(必要時易於修改)

高效代碼與 1 良好的設計 2 明智地選擇數據結構 3 明智地選擇算法 三者的密切程度,遠大於與實現語言的關係。

實踐29

常見的Java編譯器幾乎做不了什麼優化工作,所以不要依賴編譯器的優化功能(特別Java的)

我們有三個選擇:1 手動優化 2 使用第三方優化編譯器 3 依靠諸如JIT,Hotspot這樣的運行期優化策略

實踐30

理解運行期代碼優化技術

JIT的目的在於將bytecode於運行期轉換爲本機二進制碼(native binary code)。

必須確保用於[收集數據和執行優化]的時間,不能超過優化所節省的時間。並且JIT自身啓動也需要實踐。

許多嵌入式系統或許並沒有足夠的內存用於JIT或Hotspot執行層。

實踐31

如果要執行字符串連接,StringBuffer優於String

實踐32

將待建對象的數量和體積減至最小

對象構件過程中發生的順序:

1 從heap中分配內存,用於存放全部的instantce變量及這個對象連同其superclass的專有數據(域和方法指針)

2 對象的instance變量初始化對應缺省值

3 調用最深層派生類的構造函數,一直到Object

4 在構造函數本體執行前 所有instance變量初始值設定式和初始化區段先執行,再執行本體。

如果確定性能問題是由重型對象的創建造成:

1 使用緩式評估(延遲求值,lazy evaluation)

2 重新設計class

3 將class分解爲多個輕型對象,使最關鍵的部分只使用輕型對象

增加對象創建成本的特徵

1 構造函數中有大量代碼

2 內含數量衆多和龐大的對象 它們的初始化將是構造函數的一部分

3 太深的繼承層次

實踐33

只有在需要的時候再創建對象

實踐34

只有在必要的時候 才使用synchronized 並且如果整個函數需要被同步化,爲了產生體積較小且執行更快的代碼,應優先使用函數修飾符,而不是在函數內使用同步塊

實踐35

儘可能使用stack變量

stack變量爲JVM提供了更高效的bytecode指令序列,所以在循環內重複訪問static變量或instance變量時,應當將它們暫時存儲於stack變量中,以便獲得更快的運行速度。

實踐36

以方法體替換方法調用,會導致更快速的程序,如果要令函數爲inline,必須先聲明它們爲static、final或private。

實踐37

所有static變量和instance變量都會自動獲得缺省值,所以不必重新將它們設爲缺省值。隨意最好的class應該是這樣的:

 

	class A{
		private int count;
		private boolean flag;
		private Point pt;
		
		public A(){
			pt=new Point(0,0);
		}
	}

  這裏既不需要在開始對count,flag初始化,也不用在構造函數內初始化

實踐38

使用基本類型,這將比使用包裝類產生更小更快的代碼

實踐39

作遍歷時,使用get()函數而不是Enumeration或Iterator/LisIterator,這樣會導致更少的函數調用,也就意味着更快的運行速度

實踐40

使用System.arraycopy()來複制arrays。因爲這個是本機(native)函數,速度更快。 

注意copy的2個原數組和目標數組必須同類型且長度相同

實踐41

優先使用array,再考慮ArrayList和Vector

Vector最慢 因爲他是同步的 ArrayList是不帶同步的

實踐42

儘可能的複用現有的對象 但是要注意如果對象是objectreference 可能會引起不希望的結果

實踐43

採用延遲求值 lazy evaluation, 延緩那些可能永遠也不需要進行的工作

實踐44

手工優化代碼

剔除空白函數

剔除無用代碼

削減強度(例如用+=)

合併常量

刪減相同的子表達式

展開循環(會產生更多的代碼)

簡化代數

搬移循環內的不變式

實踐45

編譯爲本機代碼,通常可以獲得運行速度更快的代碼,但卻因此必須在各種不同的本機方案中取捨。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章