轉載請注明出處:http://blog.csdn.net/guolin_blog/article/details/42318689
在前兩篇文章當中,我們主要學習了Android內存方面的相干知識,包括如何公道地使用內存,和當產生內存泄漏時如何定位出問題的緣由。那末關于內存的知識就討論到這里,今天開始我們將學習1些性能編碼優化的技能。
這里先事前提示大家1句,本篇文章中討論的編碼優化技能都是屬于1些“微優化”,也就是說即便我們都依照本篇文章的技能來優化代碼,在性能方面也是看不出有甚么顯著的提升的。使用適合的算法與數據結構將永久是你優化程序性能的最主要手段,但本篇文章中不會討論這1塊的內容。因此,這里我們行將學習的其實不是甚么靈丹妙藥,而是大家應當把這些技能當作1種好的編碼規范,我們在平時寫代碼時就能夠潛移默化地使用這些編碼規范,不但能夠在微觀層面提升程序1定的性能,也能夠讓我們的代碼變得更加專業,下面就讓我們來1起學習1下這些技能。
創建對象歷來都不應當是1件隨便的事情,由于創建1個對象就意味著垃圾回收器需要回收1個對象,而這兩步操作都是需要消耗時間的。雖然說創建1個對象的代價確切非常小,并且Android 2.3版本當中又增加了并發垃圾回收器機制(詳見 Android最好性能實踐(2)――分析內存的使用情況),這讓GC操作時的停頓時間也變得難以發覺,但是這些理由都不足以讓我們可以肆意地創建對象,需要創建的對象我們自然要創建,但是沒必要要的對象我們就應當盡可能避免創建。
下面來看1些我們可以免創建對象的場景:
固然上面所說的只是1些代表性的例子,我們所要遵照的1個基本原則就是盡量地少創建臨時對象,越少的對象意味著越少的GC操作,同時也就意味著越好的程序性能和用戶體驗。
如果你其實不需要訪問1個對象中的某些字段,只是想調用它的某個方法來去完成1項通用的功能,那末可以將這個方法設置成靜態方法,這會讓調用的速度提升15%⑵0%,同時也不用為了調用這個方法而去專門創建對象了,這樣還滿足了上面的1條原則。另外這也是1種好的編程習慣,由于我們可以放心腸調用靜態方法,而不用擔心調用這個方法后是不是會改變對象的狀態(靜態方法內沒法訪問非靜態字段)。
我們先來看1下在1個類的最頂部定義以下代碼:
但是我們還可以通過final關鍵字來對上述代碼進行優化:
另外需要大家注意的是,這類優化方式只對基本數據類型和String類型的常量有效,對其它數據類型的常量是無效的。不過,對任何常量都是用static final的關鍵字來進行聲明依然是1種非常好的習慣。
增強型for循環(也被稱為for-each循環)可以用于去遍歷實現Iterable接口的集合和數組,這是jdk 1.5中新增的1種循環模式。固然除這類新增的循環模式以外,我們依然還可使用原本的普通循環模式,只不過它們之間是有效力區分的,我們來看下面1段代碼:
但是這里要跟大家提1個特殊情況,對ArrayList這類集合,自己手寫的循環要比增強型for循環更快,而其他的集合就沒有這類情況。因此,對我們來講,默許情況下可以都使用增強型for循環,而遍歷ArrayList時就還是使用傳統的循環方式吧。
Java語言當中其實給我們提供了非常豐富的API接口,我們在編寫程序時如果可使用系統提供的API就應當盡可能使用,系統提供的API完成不了我們需要的功能時才應當自己去寫,由于使用系統的API在很多時候比我們自己寫的代碼要快很多,它們的很多功能都是通過底層的匯編模式履行的。
比如說String類當中提供的好多API都是具有極高的效力的,像indexOf()方法和1些其它相干的API,雖然說我們通過自己編寫算法也能夠完成一樣的功能,但是效力方面會和這些方法差的比較遠。這里舉個例子,如果我們要實現1個數組拷貝的功能,使用循環的方式來對數組中的每個元素逐一進行賦值固然是可行的,但是如果我們直接使用系統中提供的System.arraycopy()方法將會讓履行效力快9倍以上。
我們平時寫代碼時都被告知,1定要使用面向對象的思惟去寫代碼,而面向對象的3大特性我們都知道,封裝、多態和繼承。其中封裝的基本思想就是不要把類內部的字段暴漏給外部,而是提供特定的方法來允許外部操作相應類的內部字段,從而在Java語言當中就出現了Getters/Setters這類封裝技能。
但是在Android上這個技能就不再是那末的受推重了,由于字段搜索要比方法調用效力高很多,我們直接訪問某個字段可能要比通過getters方法來去訪問這個字段快3到7倍。不過我們肯定不能僅僅由于效力的緣由就將封裝這個技能給拋棄了,編寫代碼還是要依照面向對象思惟的,但是我們可以在能優化的地方進行優化,比如說避免在內部調用getters/setters方法。
那甚么叫做在內部調用getters/setters方法呢?這里我舉1個非常簡單的例子:
這里我們注意到,getSum()方法當中的算法就是將one和two的值相加進行返回,但是它獲得one和two的值的方式也是通過getters方法進行獲得的,其實這是1種完全沒有必要的方式,由于getSum()方法本身就是Calculate類內部的方法,它是可以直接訪問到Calculate類中的封裝字段的,因此這類寫法在Android上是不推重的,我們可以進行以下修改:
固然,本篇文章中推薦的這些技能呢也其實不全面,只是從Android官方文檔抽取了幾個感覺比較實用的分享給大家,更多技能大家也能夠到Android官網上去瀏覽。另外在高性能編碼方面《Efficient Java》這本書當中也提供了非常多的技能,有興趣的朋友也能夠去瀏覽1下這本書。那末本篇文章就到這里,下篇文章當中將會介紹Android布局優化的技能,敬請期待。
第1時間取得博客更新提示,和更多技術信息分享,歡迎關注我的微信公眾號,掃1掃下方2維碼或搜索微信號guolin_blog,便可關注。