天天看點

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

編譯為本機代碼,通常可以獲得運作速度更快的代碼,但卻是以必須在各種不同的本機方案中取舍。