【威哥說】首先非常感謝這位杜同學(xué)的建議,為代碼提供優(yōu)化建議,體現(xiàn)了你的細(xì)心和技術(shù)能力,希望每一位程序員,還有我們磨礪營每一位學(xué)員,也要像這位程序員一樣,無論業(yè)務(wù)邏輯簡單或復(fù)雜,都要盡力優(yōu)化性能,只有這樣,你才能夠不斷成長,成為高級(jí)程序員!
【正文】
今天這篇性能優(yōu)化的總結(jié)源于杜同學(xué)對“Android項(xiàng)目實(shí)戰(zhàn)第二節(jié)引導(dǎo)頁實(shí)現(xiàn)”的一個(gè)建議。以下為杜同學(xué)發(fā)過來的郵件原文:
文章寫的很優(yōu)秀,趁坐地鐵的時(shí)間看了下。
個(gè)人感覺如果是真是的項(xiàng)目的話,為性能考慮,有一個(gè)小小的瑕疵:
//滑動(dòng)后的監(jiān)聽
@Override
public void onPageSelected(int position) {
//循環(huán)設(shè)置當(dāng)前頁的標(biāo)記圖
for (int i = 0; i < mImageViewArray.length; i++) {
}
}
這種做法是不可取的,雖然圓點(diǎn)圖片數(shù)量很少,雖然不費(fèi)什么內(nèi)存。
修改當(dāng)前位置的圓點(diǎn),同時(shí)復(fù)位上個(gè)位置的圓點(diǎn)。定義一個(gè)position記錄上次的圓點(diǎn)即可。
對技術(shù)比較較真,有不敬之處望見諒。
首先非常感謝這位杜同學(xué)的建議,為代碼提供優(yōu)化建議,體現(xiàn)了你的細(xì)心和技術(shù)能力,希望每一位程序員,還有我們磨礪營每一位學(xué)員,也要像這位程序員一樣,無論業(yè)務(wù)邏輯簡單或復(fù)雜,都要盡力優(yōu)化性能,只有這樣,你才能夠不斷成長,成為高級(jí)程序員!
Ok,下面我們看下他提出來的這個(gè)問題,我當(dāng)時(shí)為了實(shí)現(xiàn)方便,直接的使用循環(huán)遍歷。邏輯很簡單,就是滑動(dòng)后切換當(dāng)前選中的狀態(tài),清空上一個(gè)狀態(tài),所以,我們看出,除了當(dāng)前的和上一個(gè),其它都沒有關(guān)系,依據(jù)這邏輯我們修改下代碼:
private int priviousPosition;
//滑動(dòng)后的監(jiān)聽
@Override
public void onPageSelected(int position) {
//循環(huán)設(shè)置當(dāng)前頁的標(biāo)記圖
mImageViewArray[position].setBackgroundResource(R.mipmap.viewpager_tag_on);
mImageViewArray[priviousPosition].setBackgroundResource(R.mipmap.viewpager_tag_off);
priviousPosition = position;
首先需要定義一個(gè)int變量來記錄上一個(gè)position,然后分別改變當(dāng)前頁和上一頁的背景資源,最后把當(dāng)前頁記錄賦值給上一頁。
邏輯比較簡單,但是相比之前的循環(huán)遍歷性能上要有優(yōu)化,代碼也更簡潔,就像杜同學(xué)所說,雖然性能影響不大,但是這樣有點(diǎn)小瑕疵。
下面借這個(gè)機(jī)會(huì),我來給大家總結(jié)下項(xiàng)目開發(fā)中高性能編碼技巧:
一.避免創(chuàng)建不必要的對象
1.字符串拼接,優(yōu)先考慮StringBuffer和StringBuilder來進(jìn)行拼接
2.盡量使用基本數(shù)據(jù)類型來代替封裝數(shù)據(jù)類型,int比Integer要更加高效,其它數(shù)據(jù)類型也是一樣。
3.如果我們明確地知道調(diào)用方會(huì)將這個(gè)返回的String再進(jìn)行那個(gè)拼接操作的話,可以考慮返回一個(gè)StringBuffer對象來代替。
4.基本數(shù)據(jù)類型要優(yōu)于對象數(shù)據(jù)類型,類似的,基本數(shù)據(jù)類型的數(shù)組也要優(yōu)先于對象數(shù)據(jù)類型的數(shù)組。兩個(gè)平行的數(shù)組要比一個(gè)封裝好的對象數(shù)組更加高效,舉個(gè)例子,sun[]和num[]這樣的兩個(gè)數(shù)組,使用起來要比object(sun,num)這樣的一個(gè)數(shù)組高效的多。
我們所要遵守的一個(gè)基本原則就是盡可能少創(chuàng)建臨時(shí)對象,越少的對象意味著越少的GC操作,同時(shí)也就意味著越好的程序性能和體驗(yàn)。
二.靜態(tài)優(yōu)于抽象
如果你并不需要訪問一個(gè)對象中的某些字段,只是想調(diào)用它的某個(gè)方法來去完成一項(xiàng)通用的功能,那么可以將這個(gè)方法設(shè)置成靜態(tài)方法,這會(huì)讓調(diào)用的速度提升15%-20%,同時(shí)也不用為了調(diào)用這個(gè)方法而去專門創(chuàng)建對象了,這樣還滿足了上面的一條原則。另外這也是一種好的編程習(xí)慣,因?yàn)槲覀兛梢苑判牡恼{(diào)用靜態(tài)方法,而不用擔(dān)心調(diào)用這個(gè)方法后是否會(huì)改變對象的狀態(tài)(靜態(tài)方法內(nèi)無法訪問非靜態(tài)字段)。
三.對常量使用static final修飾符
static int num= 35; static String str = “Android”
編譯器會(huì)為上述代碼生成一個(gè)初始化方法,稱為方法,該方法會(huì)在定義類第一次被使用的時(shí)候調(diào)用。然后這個(gè)方法會(huì)將35的值賦值到num中,并從字符串常量表中提取一個(gè)引用賦值到str上。當(dāng)賦值完成后,我們就可以通過字段搜尋的方式來去訪問具體的值了。
static final int num= 35; static final String str = “Android”
修改之后,定義類不再需要方法,所有的常量都會(huì)在dex文件的初始化器中的初始化。
當(dāng)調(diào)用num時(shí)可以直接指向35的值,而調(diào)用str時(shí)會(huì)用一種相對輕量級(jí)的字符串常量方式,而不是字段搜尋的方式。這種優(yōu)化方式只對基本數(shù)據(jù)類型以及String類型的常量有效,對于其它數(shù)據(jù)類型的常量是無效的。所以,用static final聲明常量是一種非常好的習(xí)慣。
性能優(yōu)化是一個(gè)大的話題,從代碼實(shí)現(xiàn)性能優(yōu)化也有很多要注意的地方,限于篇幅,今天先給大家總結(jié)這幾個(gè)點(diǎn),希望大家持續(xù)關(guān)注公眾號(hào)(mjw-java),關(guān)注磨礪營。