Java 8的For与Stream的性能差距到底有多大?
Java 8开始引入了Stream流式操作,终于稍微可以像写Python一样写代码了,不用满大街写For语句了,但是因为这篇文章的缘故,导致我对它的性能一直抱有怀疑态度。
但是仔细分析示例中的代码,其实会发现虽然它的示例代码中使用了Stream但是其实那个很慢的结果真正大部分的时间都花在了Integer的自动装、拆箱操作上,真正的Java 8应该是怎么写这个代码呢,还是自己动手试验一下好了。
其实Stream避免反复拆装箱的话使用IntStream就可以了,Java本身为了避免出现这种装箱损耗就提供了这个工具,同时也没有必要自己写reduce函数,直接max就出结果了,但是实际上的结果是reduce更快……
因为考虑到Java的GIT优化可能性,把代码循环执行了100次。求最小值和平均值查看结果
在我这里i5 3.5G 4Core + JDK 1.8.0.102的环境下结果如下:
For total cost: 185314695, min cost: 1309517, average cost : 1834798
Stream total cost: 164412393, min cost: 1291691, average cost : 1627845
所以,Stream其实比For还要快,前提是你要用对方法。
但是仔细分析示例中的代码,其实会发现虽然它的示例代码中使用了Stream但是其实那个很慢的结果真正大部分的时间都花在了Integer的自动装、拆箱操作上,真正的Java 8应该是怎么写这个代码呢,还是自己动手试验一下好了。
package org.acgeek; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.stream.IntStream; public class ForVsStream { public static void main(String[] args) { List<long> forTest = new ArrayList<>(); List<long> streamTest = new ArrayList<>(); IntStream.range(0, 100).forEach(n -> { int[] a = new Random().ints(5000000, 1, 99999999).toArray(); int e = a.length; int m = Integer.MIN_VALUE; long thisTime = System.nanoTime(); for (int i = 0; i < e; i++) if (a[i] > m) m = a[i]; System.out.println("MAX is " + m); Long testRes = System.nanoTime() - thisTime; forTest.add(testRes); System.out.println("For use time :" + testRes); System.out.println(IntStream.of(a).toArray().length); thisTime = System.nanoTime(); // m = IntStream.of(a).max().orElse(0); // m = IntStream.of(a).reduce(Integer::max).orElse(0); m = IntStream.of(a).reduce(0, (x, y) -> x > y ? x : y); System.out.println("MAX is " + m); testRes = System.nanoTime() - thisTime; streamTest.add(testRes); System.out.println("StreamSimple use time :" + testRes); }); Long forTotal = forTest.stream().reduce(0L, Long::sum); Long streamTotal = streamTest.stream().reduce(0L, Long::sum); System.out.println("For total cost: " + forTotal + ", min cost: " + forTest.stream().reduce(Long::min).orElse(0L) + ", average cost : " + forTotal / 100); System.out.println("Stream total cost: " + streamTotal + ", min cost: " + streamTest.stream().reduce(Long::min).orElse(0L) + ", average cost : " + streamTotal / 100); } }
其实Stream避免反复拆装箱的话使用IntStream就可以了,Java本身为了避免出现这种装箱损耗就提供了这个工具,同时也没有必要自己写reduce函数,直接max就出结果了,但是实际上的结果是reduce更快……
因为考虑到Java的GIT优化可能性,把代码循环执行了100次。求最小值和平均值查看结果
在我这里i5 3.5G 4Core + JDK 1.8.0.102的环境下结果如下:
For total cost: 185314695, min cost: 1309517, average cost : 1834798
Stream total cost: 164412393, min cost: 1291691, average cost : 1627845
所以,Stream其实比For还要快,前提是你要用对方法。
评论
发表评论