Android應用性能優化的小技巧

本篇文檔主要涵蓋了一些能夠提升App整體性能的小的優化技巧,但對應用的性能不會造成大幅度的改進。大的提升和改進首要的還是選擇正確的算法和數據結構,但這兩條並不在本篇文檔的描述範圍內。在平時的編碼過程中,你就應當運用文檔中提到的技巧,這樣才能養成編寫高效的代碼的良好習慣。

編寫高效的代碼時,有兩條基本準則:

  • 不做沒必要的事。
  • 不分配沒必要的內存。

當你打算優化你的Android應用的時候,最[精妙]的是你的應用將會運行在多種不同的硬件設備上。不同版本的虛擬機運行在不同的進程,會有不同的速度。事實並不會像你所說的“設備X比設備Y跑起來要快/慢”那麼簡單,你也不能將同一個結果推廣到其它的設備。Emulator無法告知你應用在真實的設備上運行的性能。是否使用JIT也會使得設備之間有極大的不同:在一個使用JIT的設備上運行完美的代碼,在另一袋沒有JIT的設備上運行,結果通常並不那麼樂觀。
本Markdown編輯器使用[StackEdit][6]修改而來,用它寫博客,將會帶來全新的體驗哦:

避免創建不必要的對象


創建對象從來都不是無代價的。儘管垃圾回收機制使得對每個線程的臨時對象分配內存變得更加廉價,但是分配內存永遠比不分配代價更大。

當你在應用中爲了創建對象而分配了很多內存,會觸發週期性的垃圾回收,用戶體驗會有一些卡頓。同時執行的垃圾回收器在Android2.3的help文檔中有介紹,但是不必要的工作還是要儘量避免。

因此,你應當儘量避免創建不必要的對象實例。例如:

  • 如果你有一個返回類型String的方法,並且它返回的結果會被附加在StringBuffer類型後,改變你的繼承和簽名方式,使該函數直接被附加,而不是創建一個臨時的對象。
  • 當從一串輸入的數據中獲取String類型數據時,最好返回原始數據的substring,而不是建立一個copy。你會建立一個新的String對象,但是它會和原始數據共享其char[]。(其權衡之處就在於如果你只是使用原始數據的很小一部分,你將會在內存中一直保留這個數據,無論是否選擇使用這個方法)。

一個更激進的方法就是將多維數組切割成多個並列的一維數組:

  • 一個int型的數組s要比一個Integer類型的數組對象好很多,這也可以推廣到另一個問題,兩個並列的int數組要比一個(int, int)型的對象更有效率。這個原則適用於任何基本數據類型的組合。
  • 如果你需要繼承一個容器,包含了元組(Foo, Bar)對象,最好記得使用兩個並列的數組Foo[]和Bar[]將會更好。(這種情況的特例就是,當你在設計一個供其它代碼調用的API時,最好通過對速度上的妥協換來一個良好的API設計。但是在你自己的代碼中,最好還是怎麼高效怎麼來。)

總的來說,避免創建不必要的對象。較少的對象創建意味着調用垃圾回收的頻率降低,這會對用戶體驗帶來最直觀的改善。

最好使用static而不是virtual


如果你不需要在方法中調用任何對象,將方法寫成static。遠程調用(invocation)將會提高15%-20%。這也是一個優良的做法,因爲你可以通過方法標籤來判別調用的方法是否會改變對象的狀態。

常量最好使用static final


考慮在類的開始進行如下聲明:

編譯器會生成一個類的初始化方法,,在類第一次使用時執行。該方法將值“42”儲存在變量intVal中,並且在類文件的string常量表中爲變量strVal獲得一個引用。這些變量之後的引用,將會通過查詢表來獲取。

我們可以通過使用final關鍵字來提升性能:

類將不再需要初始化的方法,因爲常量將會在dex文件的靜態區初始化。調用變量intVal的相關代碼,將會直接調用值“42”,調用變量strVal的代碼將會使用相對“廉價”的string常量指令而不是表查詢。

注意:這種優化方式僅適用於基本數據類型和String常量,而不是隨便什麼類型。不過無論是否有必要,聲明一個static final的常量總是更好一些。

避免內部Getters/Setters


在native語言例如C++中,通常都會使用getters(i = getCount())而不是直接調用(i = mCount)。這是使用C++時一個良好的習慣,也經常被用在其它面嚮對象語言中,例如C#和Java。因爲編譯器通常可以內聯訪問(這些對象或變量),如果你需要限制調用或者debug,就可以在任意位置加上相關的代碼。

不使用JIT,直接調用的速度是3倍於通過getter調用的。使用JIT,直接調用則會7倍於通過getter調用。

注意: 如果你使用ProGuard,你將獲得兩種不同方式的最好體驗,因爲ProGuard可以爲你提供內聯訪問。

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