Android Note - 代碼優(yōu)化

這篇主要講一些平時寫代碼時優(yōu)化的小技巧拖云。雖然看上去都是一些很小的細(xì)節(jié)摘仅,但是積少成多,量變到一定程度也會發(fā)生質(zhì)變叮叹,積累的性能提升效果還是不可忽視的艾栋。平時碰到這些問題時一定要多留心,提升自己編碼水平的同時也能加強(qiáng)代碼的健壯性衬横。


正確選擇數(shù)據(jù)類型

這里簡單介紹一些常用的數(shù)據(jù)類型的選擇與使用場景裹粤。

String & StringBuilder

我們平時在Java中做字符串連接的時候,下意識的選擇都是使用 + 來連接。這個過程其實(shí)會新生成一個 StringBuilder 對象遥诉,然后將 + 左右的數(shù)據(jù)通過 append() 方法拼接起來拇泣,本質(zhì)上就是使用StringBuilder對象進(jìn)行字符串連接。所以在拼接頻繁的場景(比如循環(huán))中矮锈,如果使用 + 就相當(dāng)于每次都會新建一個StringBuilder對象霉翔。而我們知道,頻繁新建對象是很消耗性能的苞笨,而且在循環(huán)中也容易發(fā)生內(nèi)存抖動债朵。

結(jié)論:在單條語句中使用 + 直接拼接沒有效率問題;拼接頻繁的場景請使用 StringBuilder瀑凝。

另外序芦,還有個StringBuffer 用法與 StringBuilder幾乎一樣,只是前者是線程安全的而后者非線程安全粤咪,這里就不展開說了谚中。

基本數(shù)據(jù)類型的選擇

其實(shí)原理很簡單,不同的數(shù)據(jù)類型寥枝,占用的內(nèi)存空間不一樣宪塔。比如int只占了 4 個字節(jié),而long占用了 8 個字節(jié)囊拜,很明顯地處理起來 int 要快于 long某筐。但是,在具體的工作中冠跷,因?yàn)槭艿礁鞣N因素的制約南誊,比如第三方庫或者后端接口返回的數(shù)據(jù)往往不確定,加之性能上影響其實(shí)并不是很大蜜托,所以為了保證數(shù)據(jù)正確性弟疆,對這塊的約束一般并不是太嚴(yán)格。

結(jié)論:在自己能夠預(yù)見的場景中盡量使用int short甚至byte來代替long盗冷;float之于double同理怠苔。

包裝類的使用場景

雖然Java中針對每種基本數(shù)據(jù)類型,都有包裝類來對應(yīng)仪糖,而且對應(yīng)的包裝類都提供了自動裝箱和自動拆箱的能力柑司,但是包裝類也不能濫用。因?yàn)樵诮o包裝類賦值的時候锅劝,實(shí)際是通過valueOf方法去新建了一個對象攒驰,而基本數(shù)據(jù)類型的賦值卻是直接在棧空間內(nèi)完成的故爵,效率就快了很多玻粪。
但是不是包裝類就不要用了?也不是。包裝類作為對象劲室,提供了很多相關(guān)的操作方法兔综,方便操作色徘;另一方面如孝,包裝類可以很方便地區(qū)分賦值與未賦值的情況岁诉,而基本數(shù)據(jù)類型無法區(qū)分。這是在調(diào)用后端接口時經(jīng)常會碰到的情況喉磁,所以不能一概而論谓苟。

結(jié)論:盡量使用基本數(shù)據(jù)類型來賦值以提高效率;但是在區(qū)分賦值和未賦值的場景時請使用包裝類

變量修飾符的選擇

修飾符分為訪問控制修飾符和非訪問控制修飾符协怒。訪問控制修飾符就是我們平時見到的private protected public 等對代碼訪問權(quán)限進(jìn)行控制的符號涝焙,這里就不展開講了;這里主要談?wù)劮窃L問控制修飾符孕暇,常用的就是static final 這兩個(volatile也先略過不提)纱皆。

static 靜態(tài)修飾符 使用了該修飾符,則表示該變量隨著當(dāng)前類的生命周期共存亡芭商,并且該變量會被存到方法區(qū)(JVM中的一塊固定區(qū)域)因而可被所有對象共享,即所有實(shí)例都可以通過類名來使用該變量搀缠。

final 最終修飾符 使用了該修飾符铛楣,則表示此變量的生存期內(nèi),值是不可能改變的艺普。常量如果使用final來修飾的話簸州,讀取效率較高。

結(jié)論:很明顯歧譬,如果是常量岸浑,那么使用 static final 來修飾是可以提高效率的。


正確選擇數(shù)據(jù)結(jié)構(gòu)

在選擇數(shù)據(jù)結(jié)構(gòu)的時候瑰步,我們有時會選擇用得最順手的那個矢洲。殊不知,不同的數(shù)據(jù)結(jié)構(gòu)缩焦,執(zhí)行效率千差萬別读虏。正確選擇更好更高效的數(shù)據(jù)結(jié)構(gòu)是代碼優(yōu)化必須做到的。

ArrayList & LinkedList

這兩個數(shù)據(jù)結(jié)構(gòu)都是繼承于AbstractList并實(shí)現(xiàn)了List接口袁滥,不同之處在于ArrayList底層數(shù)據(jù)結(jié)構(gòu)使用的是數(shù)組盖桥,而 LinkedList底層數(shù)據(jù)結(jié)構(gòu)使用的是鏈表。因此在什么場合使用就很明顯了题翻。

結(jié)論:隨機(jī)查找與修改元素揩徊,使用ArrayList效率更高;對于新增和刪除元素較多的場景,則最好使用LinkedList塑荒。這是由數(shù)組和鏈表的性質(zhì)決定的

HashMap & HashSet & HashTable

這三個數(shù)據(jù)結(jié)構(gòu)都是基于Hash算法的數(shù)據(jù)結(jié)構(gòu)熄赡,但是底層實(shí)現(xiàn)都不一樣。HashMapHashTable 都是實(shí)現(xiàn)了Map 接口袜炕,但是前者繼承AbstractMap且非線程安全本谜,后者繼承的是Dictionary是線程安全的;而HashSet實(shí)現(xiàn)的則是Set接口偎窘,而且效率相對于HashMap要低一些

結(jié)論:這幾個實(shí)現(xiàn)Hash算法的數(shù)據(jù)結(jié)構(gòu)乌助,弄清楚了他們之間的區(qū)別和聯(lián)系,就能明白使用場景了

SparseArray & HashMap

具體來說陌知,SparseArray 是 Android 官方推薦的一種用來代替HashMap的數(shù)據(jù)結(jié)構(gòu)他托,更加節(jié)省內(nèi)存。但是在查找效率上仆葡,SparseArray由于查找核心算法是二分查找赏参,比HashMap稍慢一點(diǎn),但是相對來說效率損失并不是很大沿盅。

結(jié)論:在需要節(jié)省內(nèi)存空間把篓,或者對增刪改查效率要求不是非常苛刻的場景腰涧,優(yōu)先使用SparseArray

Serializable & Parcelabel

同樣的韧掩,Parcelabel 也是 Android 官方推薦的一種序列化/反序列化代碼的數(shù)據(jù)結(jié)構(gòu),比 Serializable 更加高效窖铡。因?yàn)樵谧x寫數(shù)據(jù)的時候疗锐,Parcelabel 是直接在內(nèi)存中讀寫數(shù)據(jù),而 Serializable 是通過 I/O 方式將數(shù)據(jù)讀寫在磁盤上费彼,顯然前者讀寫速度更快

結(jié)論:優(yōu)先使用 Parcelabel 序列化/反序列化滑臊,但一些場景中還是需要使用 Serializable


善于使用位運(yùn)算

在某些特定場景中,使用移位運(yùn)算比直接乘除效率要高很多箍铲,這是由計(jì)算機(jī)底層特性決定的雇卷。比如 i / 2 就可以表示為 i >> 1

結(jié)論:培養(yǎng)習(xí)慣,看到這種場景要下意識想到使用位運(yùn)算颠猴。但這樣會導(dǎo)致代碼可讀性變差聋庵,所以請清楚注釋


復(fù)用對象

因?yàn)樯梢粋€新對象在 Java 虛擬機(jī)中是一個比較耗時耗性能的操作,而且在用完這個新對象之后芙粱,系統(tǒng)還要對這些生成的對象進(jìn)行GC祭玉,這又是一筆性能開銷。所以春畔,頻繁生成過多的對象對性能會造成很大影響脱货。

結(jié)論:不要創(chuàng)建非必須的對象岛都,能復(fù)用盡量復(fù)用。尤其是要避免在循環(huán)體內(nèi)新建對象振峻,避免內(nèi)存抖動


減少不必要的全局變量

因?yàn)榕R時變量都保存在棧里臼疫,讀取速度比堆中要快;另外扣孟,棧中的變量在方法結(jié)束時就銷毀了烫堤,不需要進(jìn)行額外的GC。

結(jié)論:在不需要的地方盡量不要使用全局變量


在類的內(nèi)部直接訪問變量

請?jiān)陬惖膬?nèi)部直接訪問私有變量凤价,而不是通過 get set 方法來訪問鸽斟,可以提高代碼運(yùn)行效率。get set 方法是提供給外部調(diào)用的

根據(jù)Android官方文檔利诺,在沒有JIT(Just In Time)編譯器時富蓄,直接訪問變量的速度是調(diào)用Getter方法的3倍;在JIT編譯時慢逾,直接訪問變量的速度是調(diào)用Getter方法的7倍


循環(huán)體中的注意事項(xiàng)

循環(huán)體往往是影響效率的關(guān)鍵環(huán)節(jié)立倍,一些影響效率的因素,原理其實(shí)很簡單侣滩,所以直接說結(jié)論口注。

  1. 盡量避免在循環(huán)體中新建對象以減少內(nèi)存抖動
  2. 不要把 try ... catch 語句寫在循環(huán)體內(nèi)部

善用Lint進(jìn)行靜態(tài)代碼分析

Lint是個非常有用的工具,一般根據(jù)Lint的提示君珠,可以改進(jìn)很多代碼中不規(guī)范的地方寝志,提高效率。具體使用就不展開講了葛躏,網(wǎng)上一搜一大把


暫時先寫這么多,以后有補(bǔ)充再更新

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悠菜,一起剝皮案震驚了整個濱河市舰攒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌悔醋,老刑警劉巖摩窃,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芬骄,居然都是意外死亡猾愿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門账阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒂秘,“玉大人,你說我怎么就攤上這事淘太∫錾” “怎么了规丽?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撇贺。 經(jīng)常有香客問我赌莺,道長,這世上最難降的妖魔是什么松嘶? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任艘狭,我火速辦了婚禮,結(jié)果婚禮上翠订,老公的妹妹穿的比我還像新娘巢音。我一直安慰自己,他們只是感情好蕴轨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布港谊。 她就那樣靜靜地躺著,像睡著了一般橙弱。 火紅的嫁衣襯著肌膚如雪歧寺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天棘脐,我揣著相機(jī)與錄音斜筐,去河邊找鬼。 笑死蛀缝,一個胖子當(dāng)著我的面吹牛顷链,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屈梁,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼嗤练,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了在讶?” 一聲冷哼從身側(cè)響起煞抬,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎构哺,沒想到半個月后革答,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡曙强,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年残拐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碟嘴。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡溪食,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娜扇,到底是詐尸還是另有隱情眠菇,我是刑警寧澤边败,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站捎废,受9級特大地震影響笑窜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜登疗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一排截、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辐益,春花似錦断傲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至续捂,卻和暖如春垦垂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牙瓢。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工劫拗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人矾克。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓页慷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胁附。 傳聞我的和親對象是個殘疾皇子酒繁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容