Re: Lambda 和Streams 可以慢5倍

楼主: JustinHere (良葛格)   2015-12-03 17:03:10
※ 引述《eieio (好多目标)》之铭言:
: 佳的写法。慢五倍的关键并不是 stream,而是 boxing/unboxing
: integers.stream().reduce(...)
: integers.stream().mapToInt(Integer::intValue).reduce(...)
: 上面两个写法,有先 mapToInt 就可以避免掉过多的 boxing/unboxing,速度
: 跟 for loop 差不多。
: 同样的道理,下面这段 code 很不好:
: String r = "";
: for (String s : strs) {
: r = r + s;
: }
: 上面这段 code,每次 r = r + s 就会产生一个新的 String,效能会很低。
: 要避免产生无用的 String,要用 StringBuilder。
http://openhome.cc/Gossip/Programmer/Parallel.html
Doug Lea在〈Stream Parallel Guidance〉文件中给了一些建议,对于
S.parallelStream().operation(F),如果N为S的元素数量,而Q为F处理每个元素的成本
,可以大略使用F中的操作或行数来计算,如果N*Q至少超过10000,才有平行化的价值。
因此,如果操作简单如x -> x + 1,那么至少得有10000个以上的元素,才有平行化的价
值,相对地,如果每个元素涉及大量运算,那么就越有平行化的价值。
在Java上得考量一种处理成本:基本资料型态与对应的包裹器型态间的转换。例如,int
与Integer之间的Boxing与Unboxing操作。如果实际上List中都是数值且进行数学运算,
考虑使用mapToInt转为专属于int的IntStream,而后再进行数学运算,可免去不必要的
Boxing与Unboxing成本。目前就JDK8的Stream程式库来说,也不建议对I/O做平行处理。
在想要免于I/O、同步处理等待之类情况下,其他并行、异步I/O程式库或
CompletableFuture会是比较好的选择。
资料来源的结构也是一个考量,先前谈过,可思考将有序打为无序后,是否对平行处理有
益,另一方面,因为平行处理必须分而治之,在这之前采取易于划分的资料结构作为来源
,对平行处理会有帮助,例如支援随机存取的阵列、ArrayList或具有一定范围的
IntStream.range,平行处理时会比较有效率;而HashSet、TreeSet等,因为涉及杂凑空
间与树平衡等考量,会是其次之选;然而,像是LinkedList这类链结资料,走访划分资料
的成本是O(N),就不适合作为平行处理的来源结构,长度无法确定的资料来源,像是
Streams.iterate、BufferedReader.lines等,也不建议采用。
作者: curlywaft (culry)   2015-12-03 23:30:00
良葛格4ni

Links booklink

Contact Us: admin [ a t ] ucptt.com