Stream 是Java SE 8類庫中新增的關鍵抽象,它被定義於 java.util.stream (這個包裏有若干流類型:Stream<T> 表明對象引用流。java
此外還有一系列特化流,如 IntStream,LongStream,DoubleStream等 ),Java 8 引入的的Stream主要用於取代部分Collection的操做,每一個流表明一個值序列,流提供一系列經常使用的彙集操做,能夠便捷的在它上面進行各類運算。算法
集合類庫也提供了便捷的方式使咱們能夠以操做流的方式使用集合、數組以及其它數據結構;數組
①中間操做數據結構
②終端操做app
①只能遍歷一次:函數
數據流的從一頭獲取數據源,在流水線上依次對元素進行操做,當元素經過流水線,便沒法再對其進行操做,能夠從新在數據源獲取一個新的數據流進行操做;oop
②採用內部迭代的方式:性能
對Collection進行處理,通常會使用 Iterator 遍歷器的遍歷方式,這是一種外部迭代;學習
而對於處理Stream,只要申明處理方式,處理過程由流對象自行完成,這是一種內部迭代,對於大量數據的迭代處理中,內部迭代比外部迭代要更加高效;測試
好了,上面 stream 的優勢吹了那麼多,stream 函數式的寫法是很舒服,那麼 steam 的效率到底怎樣呢?
先說結論:
- 傳統 iterator (for-loop) 比 stream(JDK8) 迭代性能要高,尤爲在小數據量的狀況下;
- 在多核情景下,對於大數據量的處理,parallel stream 能夠有比 iterator 更高的迭代處理效率;
我分別對一個隨機數列 List (數量從 10 到 10000000)進行映射、過濾、排序、規約統計、字符串轉化場景下,對使用 stream 和 iterator 實現的運行效率進行了統計,。
測試環境以下:
System:Ubuntu 16.04 xenial
CPU:Intel Core i7-8550U
RAM:16GB
JDK version:1.8.0\_151
JVM:HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
JVM Settings:
-Xms1024m
-Xmx6144m
-XX:MaxMetaspaceSize=512m
-XX:ReservedCodeCacheSize=1024m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=100
1. 映射處理測試
把一個隨機數列(List<Integer>)中的每個元素自增1後,從新組裝爲一個新的 List<Integer>,測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `List<Integer> result = list.stream()` `.mapToInt(x -> x)` `.map(x -> ++x)` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));` `//iterator` `List<Integer> result = new ArrayList<>();` `for(Integer e : list){` `result.add(++e);` `}` `//parallel stream` `List<Integer> result = list.parallelStream()` `.mapToInt(x -> x)` `.map(x -> ++x)` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));`
2. 過濾處理測試
取出一個隨機數列(List<Integer>)中的大於 200 的元素,並組裝爲一個新的 List<Integer>,測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `List<Integer> result = list.stream()` `.mapToInt(x -> x)` `.filter(x -> x > 200)` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));` `//iterator` `List<Integer> result = new ArrayList<>(list.size());` `for(Integer e : list){` `if(e > 200){` `result.add(e);` `}` `}` `//parallel stream` `List<Integer> result = list.parallelStream()` `.mapToInt(x -> x)` `.filter(x -> x > 200)` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));`
3. 天然排序測試
對一個隨機數列(List<Integer>)進行天然排序,並組裝爲一個新的 List<Integer>,iterator 使用的是 Collections # sort API(使用歸併排序算法實現),測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `List<Integer> result = list.stream()` `.mapToInt(x->x)` `.sorted()` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));` `//iterator` `List<Integer> result = new ArrayList<>(list);` `Collections.sort(result);` `//parallel stream` `List<Integer> result = list.parallelStream()` `.mapToInt(x->x)` `.sorted()` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));`
4. 歸約統計測試
獲取一個隨機數列(List<Integer>)的最大值,測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `int max = list.stream()` `.mapToInt(x -> x)` `.max()` `.getAsInt();` `//iterator` `int max = -1;` `for(Integer e : list){` `if(e > max){` `max = e;` `}` `}` `//parallel stream` `int max = list.parallelStream()` `.mapToInt(x -> x)` `.max()` `.getAsInt();`
5. 字符串拼接測試
獲取一個隨機數列(List<Integer>)各個元素使用「,」分隔的字符串,測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `String result = list.stream().map(String::valueOf).collect(Collectors.joining(","));` `//iterator` `StringBuilder builder = new StringBuilder();` `for(Integer e : list){` `builder.append(e).append(",");` `}` `String result = builder.length() == 0 ? "" : builder.substring(0,builder.length() - 1);` `//parallel stream` `String result = list.stream().map(String::valueOf).collect(Collectors.joining(","));`
6. 混合操做測試
對一個隨機數列(List<Integer>)進行去空值,除重,映射,過濾,並組裝爲一個新的 List<Integer>,測試的隨機數列容量從 10 - 10000000,跑10次取平均時間;
`//stream` `List<Integer> result = list.stream()` `.filter(Objects::nonNull)` `.mapToInt(x -> x + 1)` `.filter(x -> x > 200)` `.distinct()` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));` `//iterator` `HashSet<Integer> set = new HashSet<>(list.size());` `for(Integer e : list){` `if(e != null && e > 200){` `set.add(e + 1);` `}` `}` `List<Integer> result = new ArrayList<>(set);` `//parallel stream` `List<Integer> result = list.parallelStream()` `.filter(Objects::nonNull)` `.mapToInt(x -> x + 1)` `.filter(x -> x > 200)` `.distinct()` `.boxed()` `.collect(Collectors.toCollection(ArrayList::new));`
實驗結果總結
從以上的實驗來看,能夠總結處如下幾點:
使用 Stream 的建議
源於:blog.csdn.net/Al\_assad/article/details/82356606