兩個小問題深入淺出List的效能問題
最近在開發中發現,在使用時,很多外掛、庫是需要我們傳入 List 資料的,而一般都會提供資料重置方法,而我發現大部分庫的資料重置方法採用的是先 clear 再 addall ,就想到 問題1:addAll的效能會更好嗎?
我的推測是,在 resetData 時,如果使用 addAll 就必須先 clear ,這樣肯定會損失一定的效能的,如果直接重新 new 一個的話,似乎效能方面會更好,而集合的 addAll 此方法按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的所有元素新增到此列表的尾部。
讓我們來看看實際的測試結果,先看看addAll的情況,程式碼如下:
private fun test() { val list= mutableListOf<String>() for (i in 1 .. 1000000){ list.add("") } Timber.e("初始時間===${monthDayFormat.format(System.currentTimeMillis())}") testList.clear() testList.addAll(list) Timber.e("結束時間===${monthDayFormat.format(System.currentTimeMillis())}") }
執行結果如下:
再來看看直接覆蓋的情況,程式碼如下:
private fun test() { val list= mutableListOf<String>() for (i in 1 .. 1000000){ list.add("") } Timber.e("初始時間===${monthDayFormat.format(System.currentTimeMillis())}") testList.clear() testList=list Timber.e("結束時間===${monthDayFormat.format(System.currentTimeMillis())}") }
執行結果如下:
可以看到,在資料量越大的情況下,直接覆蓋比addAll要快很多,但是這樣子就又有一個新的問題,在很多情況下,特別是第三方庫中的List,普遍使用final型別的情況就不能直接覆蓋。這個時候就想到
問題2:final的好處是什麼
可以查到的資料顯示,使用關鍵字 final 將有助於編譯器靜態最佳化程式碼,這最終可能導致更快的程式碼,但是他能提高的速度遠遠沒有到達非常快的速度,讓我們看下面的程式碼
public class FinalTest { public static final int N_ITERATIONS = 1000000; public static String testFinal() { final String a ="a"; final String b ="b"; return a + b; } public static String testNonFinal() { String a ="a"; String b ="b"; return a + b; } public static void main(String[] args) { long tStart, tElapsed; tStart = System.currentTimeMillis(); for (int i = 0; i < N_ITERATIONS; i++) testFinal(); tElapsed = System.currentTimeMillis() - tStart; System.out.println("Method with finals took" + tElapsed +" ms"); tStart = System.currentTimeMillis(); for (int i = 0; i < N_ITERATIONS; i++) testNonFinal(); tElapsed = System.currentTimeMillis() - tStart; System.out.println("Method without finals took" + tElapsed +" ms"); } }
看看他的執行結果:
Method with finals took 5 ms Method without finals took 273 ms
在高度最佳化的的程式下可能會有影響,到這個時候好像就沒有什麼問題了,但是我又突然想到開發的一個知識點
List集合的區別
Java 集合就像一個容器,主要由 2 大體系構成,分別是 Collection 體系和 Map 體系,其中 Collection 和 Map 分別是 2 大體系中的頂層介面 Collection 主要有三個子介面,分別為 List( 列表 ) 、 Set( 集 ) 、 Queue( 佇列 ) 。其中, List 、 Queue 中的元素有序可重複,而 Set 中的元素無序不可重複, List 中主要有 ArrayList 、 LinkedList 兩個實現類。
其中 ArrayList 底層透過陣列實現,隨著元素的增加而動態擴容, ArrayList 實現 RandomAccess ,獲得了快速隨機訪問儲存元素的功能, ArrayList 的特點是容量不固定,隨著容量的增加而動態擴容
而 LinkedList 底層透過連結串列來實現,隨著元素的增加不斷向連結串列的後端增加節點,它的特點是讀取的速度慢寫入的速度快
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69917874/viewspace-2937032/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 通過幾個問題深入淺出VueVue
- 深入淺出 eBPF|你要了解的 7 個核心問題eBPF
- 再來兩個小問題
- 由面試題“併發程式設計的三個問題”深入淺出Synchronied面試題程式設計
- Cookie出現兩個同名Key的問題Cookie
- 記錄後臺遇到的兩個小問題
- 一個小問題
- 再分享兩個小問題變成大故障的案例
- 學java就兩個問題Java
- 兩個考研政治很多人問題但是解釋通的問題
- jupyter lab 的三個小問題
- Python list,dict問題解答Python
- 深入淺出訪問者模式模式
- 一個CRM OData的效能問題分析
- Python 疑難問題:[] 與 list() 哪個快?Python
- 解決小程式web-view兩個噁心問題WebView
- 使用imp/exp遇到兩個問題
- java中list的常見問題。Java
- list is not in GROUP BY clause and contains nonaggre的問題AI
- 記錄一個小問題
- 一個極限小問題
- 集合效能問題
- QtWebEngine效能問題QTWeb
- 問題 AP: 深入淺出學演算法030-德布魯金環演算法
- 兩個看似奇怪的MySQL語句問題MySql
- 關於dcat-admin的兩個問題...
- 記一個效能優化問題優化
- pl/sql developer的一個小問題SQLDeveloper
- Redis學習的幾個小問題Redis
- 一個nvcc編譯的小問題編譯
- ab個性化實驗的效能問題
- 關於Argument list too long的問題
- 深入淺出 MySQL 優先佇列(你一定會踩到的order by limit 問題)MySql佇列MIT
- 使用CoordinatorLayout過程中遇到的兩個問題以及淺析CoordinatorLayout工作機制
- 小程式問題
- Git clone 的小問題Git
- 關於 Puerts 的效能問題
- TopK問題,陣列中第K大(小)個元素問題總結TopK陣列