2014年9月30日 星期二

【Java】for(;;)和for(:)的效能差異

【我測效能的方式一向是土法煉鋼。】



宣告一個長度在三千以上的矩陣,然後用兩種不同的for迴圈來讀取、操作內容,效能會差距多少?

注意!矩陣長度一定至少要在三千以上,一萬是比較保險的。(對矩陣個別元素的操作或運算內容也別太複雜。)

注意!還可以在for(:)的迴圈內容加個長整數,然後讓長整數一起跟著遞增,讓兩個迴圈的差異變得比較小。

答案是........




一千倍!

for(:)迴圈的速度是for(;;)迴圈的一千倍以上!




但了解技術內容的人都知道for(:)迴圈其實是將矩陣轉換成Iterator,然後用這個物件操作內容。

而且這個內容只是矩陣元素取值出來操作而已!它只是宣告一個變數,然後這個變數的值會是當下正在操作的矩陣元素的值。不論對這個變數做怎樣的操作,矩陣元素的值都不會有變化。

理論上來說,for(:)反而應該要比較慢才對,因為多了個轉換手續。

所以矩陣的長度要夠長,才會看得出差異。如果太短,這個轉換手續造成的效能差異會讓for(:)迴圈看起來比較慢。




如果有在for(:)迴圈內加長整數遞增,效能依然是一千倍!

顯然。遞增運算絕對不是效能差異的關鍵。(這很理所當然。)兩個迴圈的差異,完全在於Iterator的效能。

但差在哪裡呢?操作記憶體的效率?........傳統的for(;;)迴圈操作矩陣可能沒有位址紀錄器,要重覆的讀取迴圈內設置的長整數,還要判斷長整數的執行範圍........不過這是我隨便猜想啦!

如果在換個方法來測試這兩個迴圈的差異,例如也在傳統的for(;;)迴圈中加上一個區域變數,然後用這個區域變數取值後再對這個區域變數做運算操作,效能會差多少呢?




根本沒差!

或許關鍵根本不再Iterator,而是「變化矩陣元素內容」就是會這麼慢。






一般來說長度會到這個等級的矩陣......都是Stream吐出來的基本型別資料串。(自己寫的物件搞到三千多個?...超級資料庫?)

2014年9月17日 星期三

【Android/Java】ListView中使用ArrayAdapter搭配自己設計的物件

一般官方範例只會說到如何使用ArrayAdapter呈現String資料串。

感覺上大家會以為「ArrayAdapter只是把程式中寫在泛型資料格式指定的資料物件塞到XML Layout中的TextView上」。

但其實ArrayAdapter呼叫的是資料物件的「toString()」這個函數。


也就是說:設計師只要把「自己設定的物件」的「toString()」重新複寫就可以丟進ArrayAdapter了!

但剩下的資料呢?自己設定的物件中一定還有其他資料要顯示在ListView中,否則就不需要自定義物件了......

問這個問題的人去跪算盤!

複寫getView(int position, View convertView, ViewParent parent)這個函式就好啦!

講精準一點來說,ArrayAdapter在產生實體(new)的時候,會需要指令XML Layout跟這個Layout中的一個TextView的id。(如果不指定會預設為android.R.id.text1。)複寫的getView中如果寫了super.getView,就不用另外執行這個toString動作。(記得把super.getView傳出的View設為回傳值...記得getView這個函數要設回傳值。)




這個方法可以用在幾乎所有會用到Adapter的地方。

而且資料動態變更(執行notify函數)時,絕對會成功,因為用的是ArrayAdapter的方法。(我實作BaseAdapter產生的物件幾乎沒有成功過。)



話說......Java物件預設的函式到底還有那些?又有哪些功能?......

複寫他們會有些什麼副作用嗎?一般來說「toString()」是回傳物件的class資訊,就這樣複寫掉會有什麼影響呢?.......

有機會再補充啦。