JDK8 Stream效能問題
阿新 • • 發佈:2019-09-08
一、場景
在編寫程式碼時,想用jdk8的stream替換以前的for迴圈,程式碼如下:
//for方法
Set<String> keys = Sets.newHashSetWithExpectedSize(list.size());
for (T data : list) {
keys.add(getWrapRedisKey(data));
}
//stream方法
Set<String> keys = list.stream().map(this::getWrapRedisKey).collect(Collectors.toSet());
二、 問題
stream
for
則需要三行程式碼,生產力大大提高。
但是for
迴圈可以實現初始化容量,這在頻繁add
觸發rehash
、連結串列轉紅黑樹
時,能大大提高效能,那麼stream
的api
的Collectors.toSet
方法有沒有設定初始化容量。
檢視原始碼:
三、測試
Talking is cheap,show me the code
簡單寫了一個測試程式碼
public static void main(String[] args) { int expectSize = 100000; List<String> source = generateData(expectSize); long start = System.currentTimeMillis(); testFor(source); //testStream(source); System.out.println(System.currentTimeMillis() - start); } private static void testFor(List<String> source) { Set<String> sets = Sets.newHashSetWithExpectedSize(source.size()); for (String s : source) { sets.add(s); } } private static void testStream(List<String> source) { source.stream().collect(Collectors.toSet()); } private static List<String> generateData(int size) { List list = Lists.newArrayListWithCapacity(size); for(int i = 1; i <= size; i++) { list.add(UUIDUtils.generateId()); } return list; }
結果是10w資料是,for比stream快2-3倍...
四、 結果
在資料量比較大,同時要求相應時間場景下,應該還是使用for或者在使用stream前